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.
Related
I am trying to work with a pen having green cap tip to navigate mouse cursor using webcam but how can I get the coordinates of cap image on screen so that I can give it as input to pyinput library move function.
Thanks in advance.
# Python program for Detection of a
# specific color(green here) using OpenCV with Python
import cv2
import numpy as np
import time
cap = cv2.VideoCapture(0)
while (1):
# Captures the live stream frame-by-frame
_, frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lower_red = np.array([75, 50, 50])
upper_red = np.array([100, 255, 255])
mask = cv2.inRange(hsv, lower_red, upper_red)
res = cv2.bitwise_and(frame, frame, mask=mask)
cv2.imshow('frame', frame)
cv2.imshow('mask', mask)
cv2.imshow('res', res)
**#code to output coordinates of green pen tip**
k = cv2.waitKey(5) & 0xff
if k == 27:
break
cv2.destroyAllWindows()
cap.release()
You have all the things you need, just a couple of steps more are needed:
First find the non zero points in your mask, which should represent the tip.
points = cv2.findNonZero(mask)
Then you can averaged them to have a "unique point" which represents the tip.
avg = np.mean(points, axis=0)
Now, you can normalize this into a 0-1 value which can be later be used in any resolution... or you can normalize it directly to the resolution of the screen...
# assuming the resolutions of the image and screen are the following
resImage = [640, 480]
resScreen = [1920, 1080]
# points are in x,y coordinates
pointInScreen = ((resScreen[0] / resImage[0]) * avg[0], (resScreen[1] / resImage[1]) * avg[1] )
A few things to consider, first remember that opencv coordinate system origin is on the top left side pointing down and to the right.
---->
|
| image
|
v
Depending on where and how you use these point coordinates, you may need to flip the axis....
Second, in OpenCV points are in x,y and (at least the resolutions I wrote manually) are in width and height... you may have to adapt the code to cope with this if needed :)
If you have any questions just leave a comment
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.
I'm currently learning how to use Open CV for python and I am trying to write a program to see an image in real time from a webcam based off of an hsv value range. When I run the program I am able to get the webcam to work (it shows a black screen as expected) but the trackbars to adjust the hsv range are not showing for some reason. Anyone have any solutions? Thanks.
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
def nothing(x):
pass
#creates three trackbars for color change
cv2.createTrackbar('H','frame',0,255,nothing)
cv2.createTrackbar('S','frame',0,255,nothing)
cv2.createTrackbar('V','frame',0,255,nothing)
while(1):
# Capture frame-by-frame
_, frame = cap.read()
#creates trackbars
h = cv2.getTrackbarPos('H','frame')
s = cv2.getTrackbarPos('S','frame')
v = cv2.getTrackbarPos('V','frame')
# Converts from BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# define color strenght parameters in HSV
weaker = np.array([h+10, s+10, v+10])
stronger = np.array([h-10,s-10,v-10])
# Threshold the HSV image to obtain input color
mask = cv2.inRange(hsv, weaker, stronger)
#displays mask
cv2.imshow('Result',mask)
#terminates program
if cv2.waitKey(1) == ord('q'):
break
cv2.waitKey(0)
cv2.destroyAllWindows()
The second argument of cv2.createTrackbar('H','frame',0,255,nothing) should be the name of the window that will show the trackbars. You've used frame, but there doesn't seem to be a window named frame opened in your code. You could do so by adding
cv2.namedWindow('frame')
or by changing your display line to
cv2.imshow('frame', mask)
I have an opencv program to track a blue object here
Can someone modify it to find center of the object tracked from webcam after thresholding it to a binary image
PS: I wan this programto work with a webcam not an image
import numpy as np
import cv2
cap = cv2.VideoCapture(1)
while(True):
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
lower_blue = np.array([110,50,50])
upper_blue = np.array([130,255,255])
mask = cv2.inRange(gray, lower_blue, upper_blue)
res = cv2.bitwise_and(frame,frame, mask= mask)
# Display the resulting frame
cv2.imshow('frame',gray)
cv2.imshow('mask',mask)
cv2.imshow('res',res)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
I would like to find the center ie xy coordinates of the white blob from threshold image from webcam
I have code that i used for finding xy cordinates of a threshold image
I want to modify it for live video from webcam
HERE is the code to find co-ordinates of a binary image
for y in xrange(img.size[1]):
for x in xrange(img.size[0]):
if pixels[x, y] == 0:
xlist.append(x)
ylist.append(y)
xleft = min(xlist)
xright = max(xlist)
ytop = min(ylist)
ybot = max(ylist)
xax = (xleft+xright)/2
yax = (ytop+ybot)/2
can someone combian this 2 codes to make it work for live feed from webcam
you want to findContours after the bitwise_and, then get the boundingRect (or the moments) for the contour to get the x,y location.
and forget about your "find co-ordinates of a binary image" idea. (no, you don't want to reinvent 'connected components'. use the builtin stuff instead)
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.