2

I was trying to make a facial detection program in Python that combines Haar Cascade Classification and Lucas Kanade. But I am getting error saying something like this:

Error:

Traceback (most recent call last):
  File "/home/anthony/Documents/Programming/Python/Computer-Vision/OpenCV-Doc/optical-flow-and-haar-detection-test.py", line 80, in <module>
    corners_t = cv2.goodFeaturesToTrack(gray, mask = mask_use, **feature_params)
error: /build/buildd/opencv-2.4.8+dfsg1/modules/imgproc/src/featureselect.cpp:63: error: (-215) mask.empty() || (mask.type() == CV_8UC1 && mask.size() == image.size()) in function goodFeaturesToTrack

How my program works:

My program uses Haar Cascade to get coordinates of a detected face, copy whatever is in that area created by the coordinates (in this case, the face), take an image with nothing but black colors (all pixels are set to zero via numpy), and paste the copied face into the black background. By setting the new face with black background into the mask parameter, this would force Lucas Kanade (goodFeaturesToDetect) to create feature points on the face which will be tracked by optical flow.

Code:

from matplotlib import pyplot as plt
import numpy as np

import cv2

rectangle_x = 0


face_classifier = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_default.xml')


#cap = cv2.VideoCapture('video/sample.mov')
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()

#old_frame = cv2.imread('images/webcam-first-frame-two.png')

######Adding my code###
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.rectangle(old_frame, (x,y), (x+w, y+h), (0,255,0),2)

#initalize all pixels to zero (picture completely black)
mask_use = np.zeros(old_frame.shape,np.uint8)

#Crop old_frame coordinates and paste it on the black mask)
mask_use[y:y+h,x:x+w] = old_frame[y:y+h,x:x+w]

height, width, depth = mask_use.shape
print "Height: ", height
print "Width: ", width
print "Depth: ", depth


height, width, depth = old_frame.shape
print "Height: ", height
print "Width: ", width
print "Depth: ", depth

cv2.imshow('Stuff', mask_use)

cv2.imshow('Old_Frame', old_frame)
#cv2.imshow('Zoom in', focused_face)

face_gray = cv2.cvtColor(old_frame,cv2.COLOR_BGR2GRAY)

gray = cv2.cvtColor(focused_face,cv2.COLOR_BGR2GRAY)



corners_t = cv2.goodFeaturesToTrack(gray, mask = mask_use, **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)

    print ix, " ", iy

plt.imshow(old_frame),plt.show()
"""
print "X: ", x
print "Y: ", y
print "W: ", w
print "H: ", h
#face_array = [x,y,w,h]
"""

#############################
p0 = cv2.goodFeaturesToTrack(old_gray, mask = old_gray, **feature_params)
#############################
# 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, p0, None, **lk_params)

    # Select good points
    good_new = p1[st==1]
    ###print "Good_New"
    ###print good_new
    good_old = p0[st==1]

    # draw the tracks
    for i,(new,old) in enumerate(zip(good_new,good_old)):
        #print i
        #print color[i]
        a,b = new.ravel()
        c,d = old.ravel()
        cv2.line(mask, (a,b),(c,d), color[i].tolist(), 2)
        cv2.circle(frame,(a, b),5,color[i].tolist(),-1)
        if i == 99:
            break
        #For circle, maybe replace (a,b) with (c,d)?
    #img = cv2.add(frame,mask)

    cv2.imshow('frame',frame)
    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()

Can anyone see the problem and tell me how to fix it? Thanks.

1 Answer 1

1

I've had this error caused by using arrays that aren't the same size.

You have a for loop that dynamically assigns values to focused_face but the good_features to track uses a static size (= to the last instance of focused_face). Old_frame looks like it uses the shape of the first instance of focused_face.

Make sure you are using image and mask arrays of the same shape in goodFeaturesToTrack.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.