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.
I'm a 1st-grade cs student and I know only a little bit of python. For a project, I need to use OpenCV to detect several traffic signs. I searched a little bit on the web and I decided to use Haar-Cascade classifier. I followed this tutorial : haar-cascade
I trained the code for this sign left-sign
Everything was fine up to this point. However my code (trained with 3000 positive 1500 negative jpgs and finished 8 stages)detects both right and left signs. Code needs to recognize right and left signs separately because my aim is to command my robot to turn left or turn right.
Here is my code:
import numpy as np
import cv2
ok_cascade = cv2.CascadeClassifier('new_kocum.xml')
cap = cv2.VideoCapture(0)
while 1:
ret, img = cap.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
oks = ok_cascade.detectMultiScale(gray,3,5)
for (x,y,w,h) in oks:
cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,0),2)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,'ok',(x-w,y-h), font, 0.5, (11,255,255), 2, cv2.LINE_AA)
cv2.imshow('img',img)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
cap.release()
cv2.destroyAllWindows()
Here is the right sign : right-sign
So my question: Is it possible to fix that just by changing the code? If easier, which method should I use to detect these signs?
The correct way: you need add to the negative set a lot of the right signs.
The best way: don't use haar-cascade.
Simplest way: train the second classifier (for example naive Bayes) for comparing left and right signs after work you cascade. Features: correlation between images, Hu-moments etc.
so I have a Python program on my Raspberry Pi running on an infinite while loop that takes an image from the camera every second.
With every iteration, the program creates a thread which uses the image to process. This process consists of: a script extracts a phone screen out of the image using OpenCV and another script to extract a QR code out of that screen.
I used the program to use pre-taken images to process them without problem but it only chokes if I put the program through a continuous loop.
After a few iterations of the loop and trying to process the images, the program unexpectedly breaks and my Raspberry Pi abruptly shuts off. Does anyone know why this is happening?
I have been looking around for an answer but my suspicions are with the threads. Either, I'm overloading the CPU or RAM, there are memory leaks, the Raspberry Pi is using too much power
EDIT:
From the comments below it seems that the power supply to the Pi seems to be the problem. I'm currently running on a phone charger (5.0v, 1.0A) which is (very) below the 5.0v, 2.5A recommended power supply, darn me. I will update this post when I get a new power supply and test the code out.
Also, running the program on my Windows laptop poses no problems at all.
This is my main script:
import picamera
import threading
import time
from processing.qr import get_qr_code
from processing.scan import scan_image
# Thread method
def extract_code(file):
print 'Thread for: ' + file
# Scans image to extract phone screen from image and then gets QR code from it
scan_image(file)
get_qr_code(file)
return
# End methods
camera = picamera.PiCamera()
while True:
time.sleep(1)
# Make epoch time as file name
time_epoch = str(int(time.time()))
image_path = "images/" + time_epoch + ".jpg"
print "Taking photo: " + str(image_path)
camera.capture(image_path)
# Create thread to start processing image
t = threading.Thread(target=extract_code, args=[time_epoch])
t.start()
Below is the script to scan image (scan.py)
In a nutshell, it takes an image, blurs it, finds edges and draws contours, checks to see if there's a rectangle (e.g a phone screen) and transforms and warps it into a new image with only the phone screen.
from transform import four_point_transform
import imutils
import numpy as np
import argparse
import cv2
import os
def scan_image(file):
images_dir = "images/"
scans_dir = "scans/"
input_file = images_dir + file + ".jpg"
print "Scanning image: " + input_file
# load the image and compute the ratio of the old height
# to the new height, clone it, and resize it
image = cv2.imread(input_file)
ratio = image.shape[0] / 500.0
orig = image.copy()
image = imutils.resize(image, height = 500)
# convert the image to grayscale, blur it, and find edges
# in the image
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 75, 200)
# show the original image and the edge detected image
print "STEP 1: Edge Detection"
# find the contours in the edged image, keeping only the
# largest ones, and initialize the screen contour
_, cnts, _ = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5]
screenCnt = 0
# loop over the contours
for c in cnts:
# approximate the contour
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
# if our approximated contour has four points, then we
# can assume that we have found our screen
if len(approx) == 4:
screenCnt = approx
break
# show the contour (outline) of the piece of paper
print "STEP 2: Find contours of paper"
# if screenCnt > 0 :
# cv2.drawContours(image, [screenCnt], -1, (0, 255, 0), 2)
# apply the four point transform to obtain a top-down
# view of the original image
if screenCnt > 0:
warped = four_point_transform(orig, screenCnt.reshape(4, 2) * ratio)
print "STEP 3: Apply perspective transform"
output = scans_dir + file + "-result.png"
if not os.path.exists(scans_dir):
os.makedirs(scans_dir)
cv2.imwrite(output, imutils.resize(warped, height = 650))
else:
print "No screen detected"
This is the code to scan a QR code out of the image:
import os
from time import sleep
def get_qr_code(image_name):
scans_dir = "scans/"
codes_dir = "codes/"
input_scan_path = scans_dir + image_name + "-result.png"
output_qr_path = codes_dir + image_name + "-result.txt"
if not os.path.exists(codes_dir):
os.makedirs(codes_dir)
if os.path.exists(input_scan_path):
os.system("zbarimg -q " + input_scan_path + " > " + output_qr_path)
if os.path.exists(output_qr_path):
strqrcode = open(output_qr_path, 'r').read()
# print strqrcode
print "Results for " + image_name + ": " + strqrcode
else:
print "File does not exist"
After a few iterations of the loop and trying to process the images, the program unexpectedly breaks and my Raspberry Pi abruptly shuts off. Does anyone know why this is happening?
I had a similar experience. My program (C++) realtime processing camera frames unexpectedly crashed. Sometimes with segmentation error inside the OS code, sometimes just shutting off the whole board. Sometimes the program executable file just become zero bytes.
I taken long time looking for memory leaks or CPU peaks or other kind of programming error. Suddenly I realised that my power supply was not so strong. I changed to a new one more robust and I got no more problems.
See in this link the 2.5 A recommendation and check if your UPS actually meets this requirement.
Maybe not the answer you are looking for, but using Python with OpenCV on an embedded system is not really a good idea. I have experienced a lot of problems when using python on embedded systems (even with the powerful hardware that the rasp provides you).
All the performance problems I experienced vanished when I used C++ instead of Python. OpenCV on C++ is pretty solid and I highly recommend you to give it a try.
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.
This question already has an answer here:
How to capture multiple camera streams with OpenCV?
(1 answer)
Closed 10 months ago.
So I am attempting to capture from two cameras in openCV (python & windows 7). I capture from one camera just fine, youll also notice I am doing some funky stuff to the image but that doesn't matter. This is the code to attempt to use two
import cv
import time
cv.NamedWindow("camera", 1)
cv.NamedWindow("camera2", 1)
capture = cv.CaptureFromCAM(0)
capture2 = cv.CaptureFromCAM(1)
while True:
img = cv.GetMat(cv.QueryFrame(capture))
img2 = cv.GetMat(cv.QueryFrame(capture2))
dst_image = cv.CloneMat(img)
dst_image2 = cv.CloneMat(img2)
cv.ConvertScale(img, dst_image, 255, -59745.0)
cv.ConvertScale(img2, dst_image2, 255, -59745.0)
cv.ShowImage("camera", dst_image)
cv.ShowImage("camera2", dst_image2)
if cv.WaitKey(10) == 27:
cv.DestroyWindow("camera")
cv.DestroyWindow("camera2")
break
Rather simple. However it won't work. Upon trying to create the matrix from the second camera (second line of code in the loop), I am told that the capture is null. The cameras I am using are logitech and are the same model.
Side note: I also couldnt find the command to count cameras connected in python, so if someone could refer me to that I'd much appreciate it.
--Ashley
EDIT:
It might also be useful to know that windows often prompts me to choose which camera I would like to use. I can't seem to avoid this behavior. Additionally I downloaded some security like software that successful runs both cameras at once. It is not open source or anything like that. So clearly, this is possible.
I was having the same problem with two lifecam studio webcams. After a little reading, I think that problem related to overloading the bandwidth on the USB-bus. Both cameras began working if I 1.) lowered the resolution (320 x 240 each) or 2.) lowered the frame rate (~99 msec # 800 x 600). Attached is the code that got I working:
import cv
cv.NamedWindow("Camera 1")
cv.NamedWindow("Camera 2")
video1 = cv.CaptureFromCAM(0)
cv.SetCaptureProperty(video1, cv.CV_CAP_PROP_FRAME_WIDTH, 800)
cv.SetCaptureProperty(video1, cv.CV_CAP_PROP_FRAME_HEIGHT, 600)
video2 = cv.CaptureFromCAM(1)
cv.SetCaptureProperty(video2, cv.CV_CAP_PROP_FRAME_WIDTH, 800)
cv.SetCaptureProperty(video2, cv.CV_CAP_PROP_FRAME_HEIGHT, 600)
loop = True
while(loop == True):
frame1 = cv.QueryFrame(video1)
frame2 = cv.QueryFrame(video2)
cv.ShowImage("Camera 1", frame1)
cv.ShowImage("Camera 2", frame2)
char = cv.WaitKey(99)
if (char == 27):
loop = False
cv.DestroyWindow("Camera 1")
cv.DestroyWindow("Camera 2")
here is a small code:
import VideoCapture
cam0 = VideoCapture.Device(0)
cam1 = VideoCapture.Device(1)
im0 = cam0.getImage()
im1 = cam1.getImage()
im0 and im1 are PIL images. You can now use scipy to convert it into arrays as follows:
import scipy as sp
imarray0 = asarray(im0)
imarray1 = asarray(im1)
imarray0 and imarray1 are numpy 2D arrays, which you can furthere use with openCV functions.
In case you are using windows for coding, why dont you try VideoCapture module. It is very easy to use and gives a PIL image as output. You can later change it to a 2D array.