Please explain this opencv program for me - python

import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while(1):
# Take each frame
_, frame = cap.read()
# Convert BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# define range of blue color in HSV
lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255])
# Threshold the HSV image to get only blue colors
mask = cv2.inRange(hsv, lower_green, upper_green)
# Bitwise-AND mask and original image
res = cv2.bitwise_and(frame,frame, mask= mask)
cv2.imshow('frame',frame)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
Note: i'm new to open cv ,so please help guys!!!
In this program
while reading a frame , why is there the symbol ' _, ' before frame
is it a syntax??
The lowerbound and upper bound of blue color is specified.
is that RGB values or BGR values or HSV values??
How can i find lower bound and upperbound of others colors like red,green?
Please explain the process of finding values of other colour ,i tried other colours but it gave me black screen output for hsv and res!!!
Can some one change this program to detect red color or other color so i can know the difference?

This is tuple unpacking; cap.read() returns two values, we assign the first to _ (convention for "we won't be using this") and the second to frame.
The comment literally says "in hsv".
You just need to specify your own bounds, or change the ones already there, and see the difference yourself. Use an HSV converter to see what colours you are using. If the colours within your range aren't in the image you process, it will be black.

Related

Change Single Color in a Video with OpenCV Python

I have a video of a brick breaking game. Some bricks are in red color. I have to change the red color into black. I am trying to find the location of the red pixel in numpy array and assign black color on those pixels. The code I have provided below turns the red color into black. But the process is so slow that 12s video took more than 5 mins. Is there any faster way to do that?
import numpy as np
import cv2
vid = "input.mp4"
cap = cv2.VideoCapture(vid)
while(True):
ret, frame = cap.read()
if ret:
for i in zip(*np.where(frame == [0,0,255])):
frame[i[0], i[1], 0] = 0
frame[i[0], i[1], 1] = 0
frame[i[0], i[1], 2] = 0
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cv2.destroyAllWindows()
Try this out, read comments in the code for more information.
import cv2
import numpy as np
img = cv2.imread("1.png")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# define range of red color in HSV
lower_red = np.array([0,50,50])
upper_red = np.array([10,255,255])
# Threshold the HSV image to get only red colors
mask = cv2.inRange(hsv, lower_red, upper_red)
red_only = cv2.bitwise_and(img,img, mask= mask)
#convert mask to 3-channel image to perform subtract
mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
res = cv2.subtract(img,mask) #negative values become 0 -> black
cv2.imshow("img",img)
cv2.imshow("mask",mask)
cv2.imshow("red_only",red_only)
cv2.imshow("res",res)
cv2.waitKey()
cv2.destroyAllWindows()
PS. And this method takes almost no time, I've tested on my machine and it takes about 3ms for an image of 1280x720
This works just for gray
(you cant specify channels with color you are replacing)
color_find = [0,0,255]
indexes=np.where(frame == color_find)
frame[indexes]=0 # 0-255 creates [0,0,0] - [255,255,255]
More general attitude is like this
Here you specify RGB axis, and you can replace with any color
red = [0,0,255]
black = [0,0,0]
indexes=np.where(np.all(frame == red,axis = 2))
frame[indexes] = black
you can replace your for loop with this:
# [b,g,r]
color_in = [0, 0, 255] # color you want to filter
color_out = [0, 0, 0] # color you want to set
for i in range(3):
frame[frame[:, :, i] == color_in[i]] = color_out[i]
You can use this for video frame with 3 color channels. Also, you can play around with the conditional operator(replace with >, <, etc.) for more control.
Use like this to filter color ranges:
frame[frame[:, :, i] < color_in[i]] = color_out[i]
Using Ha Bom's code and some parts of my code, the problem has been solved. However, it takes a little bit of time. Processing 12-second video takes around 20-25 sec. The main purpose was to convert red pixels into orange-
The code is provided below -
cap = cv2.VideoCapture("input.avi")
while(True):
ret, frame = cap.read()
if ret:
# hsv is better to recognize color, convert the BGR frame to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# in hsv red color located in two region. Create the mask for red color
# mask the red color and get an grayscale output where red is white
# everything else are black
mask1 = cv2.inRange(hsv, (0,50,20), (5,255,255))
mask2 = cv2.inRange(hsv, (175,50,20), (180,255,255))
mask = cv2.bitwise_or(mask1, mask2)
# get the index of the white areas and make them orange in the main frame
for i in zip(*np.where(mask == 255)):
frame[i[0], i[1], 0] = 0
frame[i[0], i[1], 1] = 165
frame[i[0], i[1], 2] = 255
# play the new video
cv2.imshow("res",frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cv2.destroyAllWindows()

Detecting Colors on object in OpenCV - Python

I am having an issue with color detection in OpenCV 3.4. I will present a picture of my problem below.
import numpy as np
import cv2
img= cv2.imread("C:\\Users\Stefan_Cepa\\Desktop\\dataset2\\set\\A6.png")
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_range = np.array([30,150,150])
upper_range = np.array([255,255,180])
mask = cv2.inRange(hsv, lower_range, upper_range)
output = cv2.bitwise_and(img, img, mask = mask)
cv2.imshow("images", np.hstack([img, output]))
cv2.imshow('mask', mask)
while(True):
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
As you can see I've set my lower and upper bounds to detect Red color in an image, but for some reason, as you can see in image below, I am not getting any results. Any tips & tricks would be extremely helpful! Thank you in advance!
You are using the hsv colorspace but you are providing ranges of bgr values. they are incompatible.
For hsv:
For HSV, Hue range is [0,179], Saturation range is [0,255] and Value range is [0,255]. Different softwares use different scales. So if you are comparing OpenCV values with them, you need to normalize these ranges.
source: docs.opencv.org/3.2.0
Your code almost looks like this: http://pyimagesearch.com/2014/08/04/opencv-python-color-detection. Only they use bgr.
Solution:
Convert your mask-ranges to hsv or load images as bgr.
Red on hsv is on hue 0 so you probably would need a combined mask of 170-180 hue and 0-10 hue.

RGB color detection in Python Language

I am using Raspberry Pi 3 and Pi camera. I am doing an image processing program that could detect yellow colour and right now I am testing it but in frame nothing happen.My color detection is wrong?
Here is my code:
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while(1):
# Take each frame
_, frame = cap.read()
# Convert BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# define range of yellow color in HSV
lower_yellow = np.array([204,204,0])
upper_yellow = np.array([255,255,254])
# Threshold the HSV image to get only yellow colors
mask = cv2.inRange(hsv, lower_yellow, upper_yellow)
# Bitwise-AND mask and original image
res = cv2.bitwise_and(frame,frame, mask= mask)
cv2.imshow('frame',frame)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
The problem is that you're filtering an HSV image with what looks to be RGB values. If you're looking for yellow, then you want to have a narrow hue range, and then saturation and value wider.
Yellow is roughly 60 degrees for hue, which means around a value of 30 for OpenCV (as the hue value is half the degree value to it can fit in the range 0-255). Similarly, your saturation and value shouldn't be the full range of 0-255 otherwise things that are close to black or white will match.
Try something like
lower_yellow = np.array([20, 30, 30])
upper_yellow = np.array([40, 200, 300])
This will hopefully get you close, but you still may have to play around with the numbers to get what you want.

How To Detect Red Color In OpenCV Python?

I am trying to detect red color from the video that's being taken from my webcam. The following code example given below is taken from OpenCV Documentation.
The code is given below:
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while(1):
# Take each frame
_, frame = cap.read()
# Convert BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# define range of blue color in HSV
lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255])
# Threshold the HSV image to get only blue colors
mask = cv2.inRange(hsv, lower_blue, upper_blue)
# Bitwise-AND mask and original image
res = cv2.bitwise_and(frame,frame, mask= mask)
cv2.imshow('frame',frame)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
The line lower_blue = np.array([110,50,50]) has the lower range Blue HSV value and the line upper_blue = np.array([130,255,255]) has the higher range Blue HSV value. I have looked for the upper value and lower value of Red color on internet but I couldn't find it. It would be very helpful if anyone could tell the HSV value of Red for OpenCV (OpenCV H value ranges from 0 - 179).
Thanks a lot for help (In Advance).
I have also tried running the following to find the range of Red but I was unable to pick proper value maybe. What I tried was this(for red):
>>> green = np.uint8([[[0,255,0 ]]])
>>> hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
>>> print hsv_green
[[[ 60 255 255]]]
This was also taken from OpenCV documentation.
Please tell me or help me find the RANGE of RED COLOR for OpenCV.
Running the same code for red seems to work:
>>> red = numpy.uint8([[[0,0,255]]])
>>> hsv_red = cv2.cvtColor(red,cv2.COLOR_BGR2HSV)
>>> print(hsv_red)
[[[ 0 255 255]]]
And then you can try different colors that appear reddish. Beware that the red range includes both numbers slightly greater than 0 and numbers slightly smaller than 179 (e.g. red = numpy.uint8([[[0,31,255]]]) results in [[[ 4 255 255]]] whereas red = numpy.uint8([[[31,0,255]]]) results in [[[176 255 255]]].
Here is a program to determine color you need by choosing the 6 arrays parameters.(work on Opencv 3.2).
You chose your image or a "color range barre" input image and you move cursors and see which arrays values are the ones you need to isolate your color!
Color range program screen pic
here is the code:(can easily be adapted for video input).
image.jpg->(your image)
color_bar.jpg->(any image you want just to display a windows,try anything)
import cv2
import numpy as np
from matplotlib import pyplot as plt
def nothing(x):
pass
def main():
window_name='color range parameter'
cv2.namedWindow(window_name)
# Create a black image, a window
im = cv2.imread('image.jpg')
cb = cv2.imread('color_bar.jpg')
hsv = cv2.cvtColor(im,cv2.COLOR_BGR2HSV)
print ('lower_color = np.array([a1,a2,a3])')
print ('upper_color = np.array([b1,b2,b3])')
# create trackbars for color change
cv2.createTrackbar('a1',window_name,0,255,nothing)
cv2.createTrackbar('a2',window_name,0,255,nothing)
cv2.createTrackbar('a3',window_name,0,255,nothing)
cv2.createTrackbar('b1',window_name,150,255,nothing)
cv2.createTrackbar('b2',window_name,150,255,nothing)
cv2.createTrackbar('b3',window_name,150,255,nothing)
while(1):
a1 = cv2.getTrackbarPos('a1',window_name)
a2 = cv2.getTrackbarPos('a2',window_name)
a3 = cv2.getTrackbarPos('a3',window_name)
b1 = cv2.getTrackbarPos('b1',window_name)
b2 = cv2.getTrackbarPos('b2',window_name)
b3 = cv2.getTrackbarPos('b3',window_name)
# hsv hue sat value
lower_color = np.array([a1,a2,a3])
upper_color = np.array([b1,b2,b3])
mask = cv2.inRange(hsv, lower_color, upper_color)
res = cv2.bitwise_and(im, im, mask = mask)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
cv2.imshow('im',im)
cv2.imshow(window_name,cb)
k = cv2.waitKey(1) & 0xFF
if k == 27: # wait for ESC key to exit
break
elif k == ord('s'): # wait for 's' key to save and exit
cv2.imwrite('Img_screen_mask.jpg',mask)
cv2.imwrite('Img_screen_res.jpg',res)
break
cv2.destroyAllWindows()
#Run Main
if __name__ == "__main__" :
main()

Why camera capture is crashing after sometime in opencv with python?

OpenCV with python(MAC OS X EL Capitan)
I'm trying to implement simple color detection code in python using openCV.
following is my code example for color detection.
hsvTracker.py
import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)
while (1):
#take each frame
_, frame = cap.read()
#Convert BGR to HSV
hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
#define range of blue color in hsv
lower_blue = np.array([110,100,100])
upper_blue = np.array([130,255,255])
#Threshold the HSV image to get only blue colors
mask = cv.inRange(hsv, lower_blue, upper_blue)
#Bitwise-AND mask to the original image will give us tracked object
res = cv.bitwise_and(frame,frame,mask=mask)
cv.imshow('Frame',frame)
cv.imshow('mask',mask)
cv.imshow('res',res)
k=cv.waitKey(7) & 0xFF
if k == 27:
break
cv.destroyAllWindows()
When i run this code it works properly and blue color object is detected. But after some time this suddenly crashes and gives following exception stack. Is it really related to camera capture issue or is it related to something else in code?
Ask me if you want more details.

Categories

Resources