OpenCV imshow error with webcam: (-215:Assertion failed) [duplicate] - python

I am trying to make a face tracker that combines Haar Cascade Classification with Lucas Kanade good feature detection. However, I keep getting an error that I cannot figure out what it means nor how to solve it.
Can anyone help me here?
Error:
line 110, in <module>
cv2.imshow('frame',img)
error: /build/buildd/opencv-2.4.8+dfsg1/modules/highgui/src/window.cpp:269:
error: (-215)size.width>0 && size.height>0 in function imshow
Code:
from matplotlib import pyplot as plt
import numpy as np
import cv2
face_classifier = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_default.xml')
cap = cv2.VideoCapture(0)
# params for ShiTomasi corner detection
feature_params = dict( maxCorners = 200,
qualityLevel = 0.01,
minDistance = 10,
blockSize = 7 )
# Parameters for lucas kanade optical flow
lk_params = dict( winSize = (15,15),
maxLevel = 2,
criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
# Create some random colors
color = np.random.randint(0,255,(100,3))
# Take first frame and find corners in it
ret, old_frame = cap.read()
cv2.imshow('Old_Frame', old_frame)
cv2.waitKey(0)
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
restart = True
#while restart == True:
face = face_classifier.detectMultiScale(old_gray, 1.2, 4)
if len(face) == 0:
print "This is empty"
for (x,y,w,h) in face:
focused_face = old_frame[y: y+h, x: x+w]
cv2.imshow('Old_Frame', old_frame)
face_gray = cv2.cvtColor(old_frame,cv2.COLOR_BGR2GRAY)
gray = cv2.cvtColor(focused_face,cv2.COLOR_BGR2GRAY)
corners_t = cv2.goodFeaturesToTrack(gray, mask = None, **feature_params)
corners = np.int0(corners_t)
print corners
for i in corners:
ix,iy = i.ravel()
cv2.circle(focused_face,(ix,iy),3,255,-1)
cv2.circle(old_frame,(x+ix,y+iy),3,255,-1)
plt.imshow(old_frame),plt.show()
# Create a mask image for drawing purposes
mask = np.zeros_like(old_frame)
while(1):
ret,frame = cap.read()
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# calculate optical flow
p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, corners_t, None, **lk_params)
# Select good points
good_new = p1[st==1]
good_old = corners_t[st==1]
# draw the tracks
print "COLORING TIME!"
for i,(new,old) in enumerate(zip(good_new,good_old)):
print i
print color[i]
a,b = new.ravel()
c,d = old.ravel()
mask = cv2.line(mask, (a,b),(c,d), color[i].tolist(), 2)
frame = cv2.circle(frame,(a, b),5,color[i].tolist(),-1)
if i == 99:
break
img = cv2.add(frame,mask)
cv2.imshow('frame',img)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
# Now update the previous frame and previous points
old_gray = frame_gray.copy()
p0 = good_new.reshape(-1,1,2)
cv2.destroyAllWindows()
cap.release()

This error message
error: (-215)size.width>0 && size.height>0 in function imshow
simply means that imshow() is not getting video frame from input-device.
You can try using
cap = cv2.VideoCapture(1)
instead of
cap = cv2.VideoCapture(0)
& see if the problem still persists.

I have the same problem, fix the ret in capture video
import numpy as np
import cv2
# Capture video from file
cap = cv2.VideoCapture('video1.avi')
while True:
ret, frame = cap.read()
if ret == True:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame',gray)
if cv2.waitKey(30) & 0xFF == ord('q'):
break
else:
break
cap.release()
cv2.destroyAllWindows()

I had this problem.
Solution: Update the path of the image.
If the path contains (for example: \n or \t or \a) it adds to the corruption. Therefore, change every back-slash "\" with front-slash "/" and it will not make create error but fix the issue of reading path.
Also double check the file path/name. any typo in the name or path also gives the same error.

You have to delay
Example Code:
import cv2
import numpy as np
import time
cam = cv2.VideoCapture(0)
time.sleep(2)
while True:
ret,frame = cam.read()
cv2.imshow('webcam', frame)
if cv2.waitKey(1)&0xFF == ord('q'):
break
cam.release()
cv2.destroyAllWindows()

I have also met this issue. In my case, the image path is wrong, so the img read is NoneType. After I correct the image path, I can show it without any issue.

In these two lines:
mask = cv2.line(mask, (a,b),(c,d), color[i].tolist(), 2)
frame = cv2.circle(frame,(a, b),5,color[i].tolist(),-1)
try instead:
cv2.line(mask, (a,b),(c,d), color[i].tolist(), 2)
cv2.circle(frame,(a, b),5,color[i].tolist(),-1)
I had the same problem and the variables were being returned empty

I also met the error message in raspberry pi 3, but my solution is reload kernel of camera after search on google, hope it can help you.
sudo modprobe bcm2835-v4l2
BTW, for this error please check your camera and file path is workable or not

That error also shows when the video has played fine and the script will finish but that error always throws because the imshow() will get empty frames after all frames have been consumed.
That is especially the case if you are playing a short (few sec) video file and you don't notice that the video actually played on the background (behind your code editor) and after that the script ends with that error.

while(cap.isOpened()):
ret, img = cap.read()
print img
if img==None: #termino los frames?
break #si, entonces terminar programa
#gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('img2',img)

cv2.circle and cv2.lines are not working. Mask and frame both are returning None. these functions (line and circle) are in opencv 3 but not in older versions.

I use ssh to connect to remote server and have python code execute cv2.VideoCapture(0) to capture remote webcam, then encounter this error message:
error: (-215)size.width>0 && size.height>0 in function imshow
Finally, I have to grant access to /dev/video0 (which is my webcam device) with my user account and the error message was gone. Use usermod to add user into group video
usermod -a -G video user

This is a problem with space consumption or choosing the wrong camera.
My suggestion in to restart kernel and clear output and run it again.
It works then.

Although this is an old thread, I got this error as well and the solution that worked for me is not mentioned here.
Simply put, in my case the webcam was still in use on the background, as I saw the LED light being on. I have not yet been able to reproduce the issue, so I'm not sure a simple cv2.VideoCapture(0).release() would have solved it. I'll edit this post if and when I have found it out.
For me a restart of my PC solved the issue, without changing anything to the code.

This Error can also occur if you slice a negative point and pass it to the array. So check if you did

I was facing the same problem while trying to open images containing spaces and special
characters like the following ยด in their names
So, after modifying the images names removing their spaces and special characters, everything worked perfectly.

Check if you have "opencv_ffmpeg330.dll" in python27 root directory or of the python version you are using. If not you will find it in "....\OpenCV\opencv\build\bin".
Choose the appropriate version and copy the dll into the root directory of your python installation and re-run the program

Simply use an image extension like .jpeg or .png.

Related

How do I find the bounding box of this contour?

I'm relatively new to scripting. (I know quite a bit but I also don't know quite a bit.)
I'm trying to have a simple script use OpenCV-Python to subtract two frames from a webcam and draw a bounding box around the changed pixels. The issue is that when I try to define the boundingRect (x,y,w,h = cv2.boundingRect(contours)) it gives the error:
Message=OpenCV(4.5.3) :-1: error: (-5:Bad argument) in function 'boundingRect'
> Overload resolution failed:
> - array is not a numpy array, neither a scalar
> - Expected Ptr<cv::UMat> for argument 'array'
I've been searching around for quite a while but there seems to be a very small number of people who've had my issue and pretty much none of them had solutions that worked.
Here's my code:
import cv2
from time import sleep as wait
import numpy as np
lastFrame = "foobaz"
i = 0
#My webcam is on index 1, this isn't (at least shouldn't) be the issue. Make sure to set it back to 0 if you are testing
vid = cv2.VideoCapture(1)
#A placeholder black image for the 'subract' imshow window
black = np.zeros((512,512,3), np.uint8)
while(True):
wait(0.5)
ret, frame = vid.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
blurframe = cv2.GaussianBlur(frame,(25,25),0)
#Makes sure the lastFrame has been assigned, if not set it as placeholder black image.
if lastFrame != "foobaz":
#Subtracts current frame and the last frame to find difference.
subFrame = cv2.subtract(blurframe,lastFrame)
else:
subFrame = black
#Assigns the next lastFrame
lastFrame = blurframe
#Gets the threshold of the subtracted image
ret,thresh1 = cv2.threshold(subFrame,40,255,cv2.THRESH_BINARY)
#Sets the thresholded image to grayscale if the loop was ran for the first time.
if i==0:
thresh1 = cv2.cvtColor(thresh1, cv2.COLOR_BGR2GRAY)
i+=1
#This is where issues arize. I'm trying to apply a bounding box using a contour but it always errors at line 44.
contours = cv2.findContours(thresh1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
print(len(contours))
x,y,w,h = cv2.boundingRect(contours)
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow('frame',frame)
cv2.imshow('subtract',thresh1)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
I saw that some other posts had the contour type() so here it is:
type(contours) = <class 'list'>
CLOSED: I found out the issue. You have to iterate contours for it to work.

MOG background subtraction: history parameter not working

I'm trying to use MOG background subtraction but the "history" function doesn't seem to work.
OpenCV 2.4.13
Python (2.7.6)
Observation: The program appears to use the very first frame it captures for all future background subtractions.
Expectation: The background should slowly evolve based on the "history" parameter, so that if the camera angle changes, or if a person/object leaves the field-of-view, the "background" image will change accordingly.
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
mog = cv2.BackgroundSubtractorMOG(history=10, nmixtures=5, backgroundRatio=0.25)
while True:
ret, img1 = cap.read()
if ret is True:
cv2.imshow("original", img1)
img_mog = mog.apply(img1)
cv2.imshow("mog", img_mog)
if cv2.waitKey(10) & 0xFF == ord(q):
break
video_capture.release()
cv2.destroyAllWindows()
Thank you in advance for your help!

Ball/circle shape tracking in video or live feed with OpenCV (Python)

As a task for school our group has to create an application that knows when a goal is scored. This means that a ball shaped object passes a line.
First we are attempting to input a video, get OpenCV to track the ball, and then to output it as a video.
I have put a bunch of other code snippets together that I have found on StackOverflow, but it doesn't work.
I am creating a new post because all the other related threads are either C++ or use colour detection instead of the shape detection that we use. I also can't find a clear answer on outputting the video file when it was turned into a series of images.
Following is the code that I have so far:
import cv2
import numpy as np
cap = cv2.VideoCapture('bal.mp4')
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output1.avi',fourcc, 20.0, (640,480))
while(1):
# Take each frame
ret, frame = cap.read()
if ret == True:
if ret == 0:
break
frame = cv2.medianBlur(frame,5)
cimg = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
circles = cv2.HoughCircles(cimg,3,1,20,param1=50,param2=30,minRadi$
if circles == None:
print "NoneType"
break
circles = np.uint16(np.around(circles.astype(np.double),3))
for i in circles[0,:]:
# draw the outer circle
cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
# draw the center of the circle
cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)
cv2.imwrite('test.jpg',cimg)
out.write(cimg)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()
We get working images, but the video is unplayable with VLC or any other media player.
This is an image from the program:
This issue is turning it into a playable video now.
Thanks in advance.
Not sure if you got this working in the end, but changing it to mp4 worked for me on my mac
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
out = cv2.VideoWriter('static/video/outpy.mp4', 0x7634706d, 20, (frame_width, frame_height))

Track circles in video OpenCV

import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while(1):
# Take each frame
_, frame = cap.read()
frame = cv2.medianBlur(frame,5)
cimg = cv2.cvtColor(frame,cv2.COLOR_GRAY2BGR)
circles = cv2.HoughCircles(frame,cv2.HOUGH_GRADIENT,1,20,
param1=50,param2=30,minRadius=0,maxRadius=0)
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
# draw the outer circle
cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2)
# draw the center of the circle
cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3)
cv2.imshow('frame',cimg)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
I am trying to find circles, but my code fails OpenCV Error: Assertion failed (scn == 1 && (dcn == 3 || dcn == 4)). Any idea why? In addition, how to get coordinates of a circle?
The flag you pass to cvt Color should be cv2.COLOR_BGR2GRAY instead of cv2.COLOR_GRAY2BGR - you want convert to grayscale to have single channeled image instead of RGB 3 channeled image and that's what assertion says. (look at the docs to see what paramaters you need, an input image is clearly a 8-bit, single-channel, grayscale input image.)
Rest of the code looks ok and is an answer to second part of your question.
EDIT: (after OP having another problem with passing constant):
After changing cvtColor constant we had following code:
cimg = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
circles = cv2.HoughCircles(cimg,cv2.HOUGH_GRADIENT,1,20,
param1=50,param2=30,minRadius=0,maxRadius=0)
which actually caused another problem:
AttributeError: 'module' object has no attribute 'HOUGH_GRADIENT'
Since I'm working with OpenCV mostly with C++ and not with Python, I solved it in different way. I tried to find number equivalent of CV_HOUGH_GRADIENT constant. In turned out to be located in opencv\sources\modules\imgproc\include\opencv2\imgproc\types_c.h:
enum
{
CV_HOUGH_STANDARD =0,
CV_HOUGH_PROBABILISTIC =1,
CV_HOUGH_MULTI_SCALE =2,
CV_HOUGH_GRADIENT =3
};
That is why we can use following snippet instead of predefined constant:
circles = cv2.HoughCircles(cimg,3,1,20, param1=50,param2=30,minRadius=0,maxRadius=0)

opencv/python : motion detect weird thresholding

I am trying to make a motion detect program using my webcam, but I'm getting this weird results when thresholding the difference of frames:
When Im moving: (seems okay I guess)
![enter image description here][1]
When Im not moving:
![enter image description here][2]
What can this be? I already ran a couple of programs that got exactly the same algorithm and the thresholding is doing fine..
Heres my code:
import cv2
import random
import numpy as np
# Create windows to show the captured images
cv2.namedWindow("window_a", cv2.CV_WINDOW_AUTOSIZE)
cv2.namedWindow("window_b", cv2.CV_WINDOW_AUTOSIZE)
# Structuring element
es = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9,4))
## Webcam Settings
capture = cv2.VideoCapture(0)
#dimensions
frameWidth = capture.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)
frameHeight = capture.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)
while True:
# Capture a frame
flag,frame = capture.read()
current = cv2.blur(frame, (5,5))
difference = cv2.absdiff(current, previous) #difference is taken of the current frame and the previous frame
frame2 = cv2.cvtColor(difference, cv2.cv.CV_RGB2GRAY)
retval,thresh = cv2.threshold(frame2, 10, 0xff, cv2.THRESH_OTSU)
dilated1 = cv2.dilate(thresh, es)
dilated2 = cv2.dilate(dilated1, es)
dilated3 = cv2.dilate(dilated2, es)
dilated4 = cv2.dilate(dilated3, es)
cv2.imshow('window_a', dilated4)
cv2.imshow('window_b', frame)
previous = current
key = cv2.waitKey(10) #20
if key == 27: #exit on ESC
cv2.destroyAllWindows()
break
Thanks in advance!
[1]: http://i.stack.imgur.com/hslOs.png
[2]: http://i.stack.imgur.com/7fB95.png
The first thing that you need is a previous = cv2.blur(frame, (5,5)) to prime your previous sample after a frame grab before your while loop.
This will make the code you posted work, but will not solve your problem.
I think the issue that you are having is due to the type of thresholding algorithm that you are using. Try a binary, cv2.THRESH_BINARY, instead of Otsu's. It seemed to solve the problem for me.

Categories