Search code examples
pythonimageopencvimage-processingimage-resizing

Python OpenCV: Cannot resize image


I am using Python 3 and OpenCV 3. I am trying to use the EigenFace Recognizer which uses the same size images for the training and test dataset. I read the image from a webcam and I resize the images to 200 x 200 but it shows an error .

This is my code:

faceDetect=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
cam=cv2.VideoCapture(0);
rec=cv2.face.EigenFaceRecognizer_create()
#rec=cv2.face.LBPHFaceRecognizer_create()
rec.read("recognizer/EigenData.xml")
id=0

fontFace = cv2.FONT_HERSHEY_SIMPLEX
fontScale = 1
fontColor = (0, 0, 255)

while(True):
    ret,img=cam.read();

    resize_img = img.resize((200,200) , img)
    gray=cv2.cvtColor(resize_img,cv2.COLOR_BGR2GRAY)
    faces=faceDetect.detectMultiScale(gray,1.3,5);

    for(x,y,w,h) in faces:

        cv2.rectangle(img,(x,y),(x+w, y+h), (0,255,0) , 2)
        id, conf=rec.predict(gray[y:y+h, x:x+w])   #EigenFace Predict
        cv2.putText(img,str(id),(x,y+h), fontFace, fontScale, fontColor,thickness=2)

    cv2.imshow("Face", img);
    if(cv2.waitKey(1)==ord('q')):
        break;

cam.release()
cv2.destroyAllWindows()

The error I get is:

resize_img = img.resize((200,200) , img)
TypeError: 'tuple' object cannot be interpreted as an integer

Solution

  • OpenCV uses NumPy arrays as the fundamental datatype to represent images. Indeed NumPy has a resize method to "resize" the data, but you're not using it properly. By consulting the documentation, the numpy.resize method requires you to reverse the order of your parameters. The input array goes first followed by the desired size. You have it almost correct - just swap the order of the arguments.

    However, I don't believe this is what you're looking for since numpy.resize fills in the output array with repeated copies of the input - especially since you're doing this for facial recognition. I believe you want to resize the contents of the image to fit the desired size, not fill in the array with repeated copies of the input with its original size intact.

    Therefore, cv2.resize is a better fit for you. You call it the same way as numpy.resize:

    resize_image = cv2.resize(img, (200,200))
    

    Take note that the default method of resizing uses bilinear interpolation. If you want to use another method, you will have to provide an additional argument interpolation to do that. If you wanted to perform cubic interpolation, you would do:

    resize_image = cv2.resize(img, (200,200), interpolation=cv2.INTER_CUBIC)
    

    Check the documentation on cv2.resize for more details: https://docs.opencv.org/3.0-beta/modules/imgproc/doc/geometric_transformations.html#resize