Why DSHOW can control white balance but OpenCV cannot?

Viewed 2962

I'm working on a Windows standalone app which require to take pictures that will be then be edited.

For both capturing and editing, I am using OpenCV.

To keep a consistent behaviour in my editing process, I would like to disable Auto Exposure and Auto White Balance.

I managed to control exposure with OpenCV, but not White Balance. Although, when I'm using the DSHOW panel, I can change White Balance.

DSHOW with OpenCV

To open the DSHOW panel, I use the following:

cam.set(cv2.CAP_PROP_SETTINGS, 1)

From OpenCV, I can read the White Balance value setting, but I can't edit it (set(...) returns False when I try to do it). And I can't even read the Auto White Balance setting.

Auto WB  -1.0
XI Auto WB  -1.0
XI Manual WB  -1.0
WB Temp  -1.0
WB Blue U  5415.0
WB Red V  -1.0

According to what I read online, we cannot rely too much on this API as most cameras don't follow the specs.

I'm wondering what the DSHOW panels does that OpenCV can't ?

Here is the full script:

import cv2

# I choose DSHOW backend to be able to open
# the dshow settings window
cam = cv2.VideoCapture(0, cv2.CAP_DSHOW)

cv2.namedWindow("test")

img_counter = 0

while True:
    ret, frame = cam.read()
    if not ret:
        print("failed to grab frame")
        break
    cv2.imshow("test", frame)

    k = cv2.waitKey(1)

    # Quit
    if k == ord('q') or k == ord('Q'):
        print("Closing...")
        break
    # Open DShow control panel.
    elif k == ord('p') or k == ord('P'):
        print("Opening director show panel control...")
        print(cam.set(cv2.CAP_PROP_SETTINGS, 1))
    # Toggle white balance
    elif k == ord('t') or k == ord('T'):
        print("Change white balance value. Trying different things...")
        print(cam.set(cv2.CAP_PROP_AUTO_WB, 1))
        print(cam.set(cv2.CAP_PROP_AUTO_WB, 0))
        print(cam.set(cv2.CAP_PROP_AUTO_WB, True))
        print(cam.set(cv2.CAP_PROP_AUTO_WB, False))
        print(cam.set(cv2.CAP_PROP_XI_MANUAL_WB, 1))
        print(cam.set(cv2.CAP_PROP_XI_MANUAL_WB, 0))
        print(cam.set(cv2.CAP_PROP_XI_AUTO_WB, 1))
        print(cam.set(cv2.CAP_PROP_XI_AUTO_WB, 0))
    # Show white balance
    elif k == ord('w') or k == ord('W'):
        print("White balance settings :")
        print("Auto WB ", cam.get(cv2.CAP_PROP_AUTO_WB))
        print("XI Auto WB ", cam.get(cv2.CAP_PROP_XI_AUTO_WB))
        print("XI Manual WB ", cam.get(cv2.CAP_PROP_XI_MANUAL_WB))
        print("WB Temp ", cam.get(cv2.CAP_PROP_WB_TEMPERATURE))
        print("WB Blue U ", cam.get(cv2.CAP_PROP_WHITE_BALANCE_BLUE_U))
        print("WB Red V ", cam.get(cv2.CAP_PROP_WHITE_BALANCE_RED_V))

cam.release()

cv2.destroyAllWindows()
1 Answers

I managed to control the camera auto white balance and exposure using Direct Show. Unfortunately, this can't be done from OpenCV at the moment.

Related