0

I'm trying to make a python program with OpenCV, which opens the webcam and takes several images with different exposures in real time (40ms,95ms,150ms) and averages them in the end. I tried to create a loop in which I change the exposure time, update the rendering (frame) and save it in a list, but the problem is that the display remains static and the rendering hardly changes (which gives after merging the images an image whose exposure time is almost 40)

I supposed that after setting exposure time, the frame update needs some time so I added the method time.sleep to suspend the execution for 3 seconds, but it was in vain.

Here is my code

import numpy as np
import cv2
import os
import time

capture = cv2.VideoCapture(0, cv2.CAP_V4L2)

while True:
    (grabbed, frame) = capture.read()

    if not grabbed:
        break

    # Resize frame
    width = 1500
    height = 1000
    dim = (width, height)
    frame = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)
    
    cv2.imshow('RGB', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

    if cv2.waitKey(1) == ord('h') or cv2.waitKey(1) == ord('H'):
        #repertory = input("Enter the name of the directory: ")
        if not os.path.exists(repertory):
            os.mkdir(repertory)
        exposure = [40,95,150]
        ims = []
        for i in exposure:
            capture.set(cv2.CAP_PROP_EXPOSURE, i) # Setting Exposure
            (grabbed, frame) = capture.read() # Updating frame
            if grabbed:
                cv2.imshow('RGB', frame) #Display
                ims.append(frame)


        # Convert to numpy
        ims = np.array([np.array(im) for im in ims])
        # average et conversion en uint8
        imave = np.average(ims, axis=0)
        imave = imave.astype(np.uint8)

        # image HDR
        cv2.imwrite(repertory + '/' + repertory + '_HDR8.jpg', imave)


capture.release()
cv2.destroyAllWindows()

Is there an optimal solution that allows to take pictures with differents exposure time in real time and in an automatic way?

  • I specify that the auto-exposure mode is disabled `capture.set(cv2.CAP_PROP_AUTO_EXPOSURE, 1)` – Omar Benjelloun May 21 '21 at 15:15
  • I remember once having a problem, that in between exposure changes, I had to discard frames until the new exposure setting was applied. – ai2ys May 21 '21 at 15:31
  • 1
    Have you tried grabbing frames, storing them. During this changing the exposure and checking afterwards how many frames it takes until the change in exposure gets applied? – ai2ys May 21 '21 at 20:26
  • **1.** What is the video framerate? The exposure time cannot exceed the frame period. For 25fps, the maximum is about 40msec, and for 10fps, the maximum is about 100msec. **2.** For best results, you need to capture **raw** video frames (not possible with a webcam). The camera image processing might naturalize the effect of the different exposure times. – Rotem May 21 '21 at 20:31
  • @ai2ys I tried this by taking 3 images with different exposures (40,95,150) and storing them and then I created a while loop that makes the renderer update until it is equal to the loaded target image. Unfortunately, the loop is infinite. Is there an efficient way to do this? – Omar Benjelloun May 22 '21 at 13:35
  • 1
    @OmarBenjelloun I mean something different. Create a loop, where you capture let’s say 30 images. After 10 frames change the exposure time within the loop call. Save all of the images. Check the images, from the 10th frame on you should expect a change in exposure. Check if it is the 11th frame or any other frame later on. Then you would know how many frames to capture until the new setting is valid. – ai2ys May 22 '21 at 13:35
  • @ai2ys I just did this and saved for each exposure 50 images, then I noticed that the first setting (40ms) took place after 8 frames saved and the other settings after only 3 frames Thank u – Omar Benjelloun May 22 '21 at 14:03
  • @Rotem the video frame rate is 9.0 . Since I use 150ms as an exposure time, I need to have up to 6fps in frame rate. However, I can't change the FPS with `capture.set(cv2.CAP_PROP_FPS,6)`. – Omar Benjelloun May 22 '21 at 14:08
  • @OmarBenjelloun you could upvote the comments that helped you, so that other people having the same issue will see them and it will help them, too. – ai2ys May 23 '21 at 20:35
  • @ai2ys Yes for sure, but I need 15 reputation to upvote comments, so I'll do it later ! – Omar Benjelloun May 25 '21 at 09:41

0 Answers0