pythonopencvarmwebcamodroid

OpenCV webcam image broken


I wrote a script in Python3 and OpenCV 3.1 for timelapse photos on Odroid C1:

Unfortunately sometimes images from the webcam are messed up: Here's are some example photographs.

enter image description here enter image description here

And here's the source code:

import numpy as np
import cv2
import time
import datetime
import sys

cap = cv2.VideoCapture(0) # USB webcam

cap.set(3,2304.0) #  Resolution: Width
cap.set(4,1296.0) # Resolution: Height
cap.set(5, 6) #webcam capture FPS 
print(str(cap.get(3)),str(cap.get(4)),str(cap.get(5)))


def captureImage():
         ret, frame = cap.read()
         curr_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
         filename = 'littleGarden_'+curr_time +'.jpg'
         file_to_save = folder_to_save + filename
         cv2.imwrite(file_to_save,frame)
         print("File saved ", file_to_save)


ret, frame = cap.read()
while(True):
    # Capture frame-by-frame
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    captureImage()
    time.sleep(delay)

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

For reference, the first argument in the cap.set() command refers to the enumeration of the camera properties, listed below:

0. CV_CAP_PROP_POS_MSEC Current position of the video file in milliseconds.
1. CV_CAP_PROP_POS_FRAMES 0-based index of the frame to be decoded/captured next.
2. CV_CAP_PROP_POS_AVI_RATIO Relative position of the video file
3. CV_CAP_PROP_FRAME_WIDTH Width of the frames in the video stream.
4. CV_CAP_PROP_FRAME_HEIGHT Height of the frames in the video stream.
5. CV_CAP_PROP_FPS Frame rate.

Is there any way to fix it?


Solution

  • You are not working with a video file. It is not clear to me what options you are setting but it could be a problem with your set calls on your VideoCapture object. Keep in mind that you are working with a camera so there is no index to skip if I remember correctly.

    EDIT: Jack, I think you should be able to access the correct constants by using cv2.cv.CV_CAP_PROP_FPS etc. Assuming your camera driver implemented these ioctls you would receive 3 frames per seconds. However only one picture per second would be written by the imwrite() call as you are overwriting the other two.

    You should test your received Mat without writing them down directly with the highgui imshow if possible. Test that without setting anything and report back.