Search code examples
pythonopencvmatrixwindow

Python Opencv black window


Using python and opencv I am averaging an image over 20 images with .5 second between them. I have used this library successfully so far, but this one is giving me a problem. This is my code

import numpy as np
import cv2
import time

webcam = cv2.VideoCapture(0)
webcam.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 640)
webcam.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 480)
webcam.set(cv2.cv.CV_CAP_PROP_EXPOSURE, .2)

total = np.zeros((480,640,3), int)
time.sleep(0.500)
x = 0
while x < 19:
    retval, img = webcam.read()
    if(retval == True):
        total += img;
        time.sleep(0.500)
        x += 1

result = np.zeros((480,640,3), int)
result = np.divide(total, 20, dtype=int)

cv2.namedWindow("result",cv2.cv.CV_WINDOW_AUTOSIZE)
cv2.cv.MoveWindow("result", 0, 0)
while True:
    cv2.imshow("result", result)
    if(cv2.waitKey(10) == 27):
        break

cv2.destroyAllWindows()
webcam.release()

Whilst running this program gives no error, it does display a black image. The img variable returns a working image however. The averaging probably creates the error here, but as far as I know the contents of the result matrix is correct.


Solution

  • You mix np.uint8 and int32 in OpenCV, which causes All Blacks to appear.

    While you need for sure an accumulator array total to have sufficient bit-depth for an incremental += summing phase, but your np.divide(), which you want to pass to a cv2.imshow() shall result in display-able dtype = np.uint8

    result = np.zeros( (480,640,3),        np.uint8 )    # needless to pre-allocate
    result = np.divide( total, 20, dtype = np.uint8 )    # just enough to assign here
    

    n.b.1:

    You might also note a typo in double .set() which does not make any issue if VideoCapture() device still returns array of (480,640,3) np.uint8-s

    webcam.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 640)
    webcam.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 480)
    #                                   |||||  ^^^