Dynamic webcam control (update)

I have also rearranged some parts of the script. The system call for uvcdynctrl  was moved into the function set_webcam(), with exposure, priority, balance, sharpness, absolute, brightness, contrast, saturation, gain and compensation as function parameters.

# Import some modules
from PIL import Image, ImageStat
import sys
import os
import pygame
import datetime
import time
import ephem
import pygame.camera

# Function to test average brightness of the captured image
def get_brightness(): 
        image = cam.get_image()
        data = pygame.image.tostring(image, 'RGB')
    grey = Image.fromstring('RGB', (640,480), data).convert('L')
    stat = ImageStat.Stat(grey)
    return int(stat.rms[0])

# Function to adjust webcam settings.
def set_webcam(exposure, priority, balance, sharpness, absolute, brightness, contrast, saturation, gain, compensation):
    os.system('sudo uvcdynctrl --set="Exposure, Auto" {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}s' {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}exposure)
        os.system('sudo uvcdynctrl --set="Exposure, Auto Priority" {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}s' {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}priority)
        os.system('sudo uvcdynctrl --set=Gain {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}s' {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}gain)
        os.system('sudo uvcdynctrl --set="Backlight Compensation" {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}s' {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}compensation)
        if exposure == 1:
            os.system('sudo uvcdynctrl --set="Exposure (Absolute)" {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}s' {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}absolute)
        if init == 0:
                os.system('sudo uvcdynctrl --set="White Balance Temperature, Auto" {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}s' {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}balance)
                os.system('sudo uvcdynctrl --set=Sharpness {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}s' {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}sharpness)
                os.system('sudo uvcdynctrl --set=Brightness {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}s' {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}brightness)
                os.system('sudo uvcdynctrl --set=Contrast {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}s' {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}contrast)
                os.system('sudo uvcdynctrl --set=Saturation {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}s' {c7f7cb1468c0d02af358b3ce02b96b7aadc0ce32ccb53258bc8958c0e25c05c4}saturation)
        return

# Set location, latitude and longitude for sunset/sunrise calculation
Berlin=ephem.Observer()
Berlin.lat='52'
Berlin.long='13'
Sun=ephem.Sun()
Sun.compute()

# Calculate next/previous sunset, sunrise and retrieve system time
n_rising = ephem.localtime(Berlin.next_rising(Sun))
p_rising = ephem.localtime(Berlin.previous_rising(Sun))
n_setting = ephem.localtime(Berlin.next_setting(Sun))
p_setting = ephem.localtime(Berlin.previous_setting(Sun))
now = datetime.datetime.fromtimestamp(time.time())

# Calculate time from now until next/previous sunrise/sunset in minutes
delta_n_rising = round(abs(datetime.timedelta.total_seconds(now - n_rising))/60)
delta_p_rising = round(abs(datetime.timedelta.total_seconds(now - p_rising))/60)
delta_n_setting = round(abs(datetime.timedelta.total_seconds(now - n_setting))/60)
delta_p_setting = round(abs(datetime.timedelta.total_seconds(now - p_setting))/60)

# Enable for debugging of time formats
#print(now)
#print(rising)
#print(setting)

# Initialize webcam resolution and reset camera to auto settings
# Camera must be reset to calculate average image brightness
init = 0
set_webcam(3, 1, 1, 128, 0, 85, 45, 30, 255, 1)
init = 1
pygame.camera.init()
cam = pygame.camera.Camera("/dev/video0",(640,480))
cam.start()

# Get brightness value, save average brightness value to logfile for debugging/calibration
image_brightness = 1 # it is necessary to initialize this variable before use
for i in range(1, 3):
   image_brightness += get_brightness()
image_brightness = int(image_brightness / 3)
f = open('/var/www/data/log.txt', 'a') # append to file for debugging
sys.stdout = f
print( time.ctime(), image_brightness )

# Adjust exposure and and gain conditionally according daytime
if delta_n_rising < 20:
    # BEFORE sunrise
    if 0 < image_brightness <= 30:
       set_webcam(1, 0, 1, 0, 1024, 0, 0, 0, 200, 0)
    else:
       set_webcam(3, 1, 1, 0, 0, 0, 0, 0, 255, 0)
elif delta_p_rising < 75:
    # AFTER sunrise
    if 0 < image_brightness <= 30:
       set_webcam(1, 0, 1, 128, 1024, 85, 45, 40, 200, 0)
    else:
       set_webcam(3, 1, 1, 0, 0, 0, 0, 0, 255, 0)
elif delta_n_setting < 75:
    # BEFORE sunset
    if 0 < image_brightness <= 30:
       set_webcam(1, 0, 1, 0, 1024, 0, 0, 0, 200, 0)
    else:
       set_webcam(3, 1, 1, 0, 0, 0, 0, 0, 255, 0)
elif delta_p_setting < 20:
    # AFTER sunset
    if 0 < image_brightness <= 30:
       set_webcam(1, 0, 1, 0, 1024, 0, 0, 0, 200, 0)
    else:
       set_webcam(3, 1, 1, 0, 0, 0, 0, 0, 255, 0)
elif  n_rising > n_setting:
    # DAYTIME
    #if image_brightness >= 250:
    #   set_webcam(1, 0, 1, 0, 3, 0, 0, 0, 100, 1)
    #elif 100 < image_brightness <= 120:
    #   set_webcam(1, 0, 1, 0, 120, 0, 0, 0, 160, 0)
    #elif 80 < image_brightness <= 100:
    #   set_webcam(1, 0, 1, 0, 155, 0, 0, 0, 170, 0)
    #elif 30 < image_brightness <= 80:
    #   set_webcam(1, 0, 1, 0, 190, 0, 0, 0, 180, 0)
    #elif 0 < image_brightness <= 30:
    #   set_webcam(1, 0, 1, 0, 1024, 0, 0, 0, 200, 0)
    #else:
    set_webcam(3, 1, 1, 0, 0, 0, 0, 0, 255, 1)
elif n_setting > n_rising:
    # NIGHT
    set_webcam(1, 0, 1, 0, 2047, 0, 0, 0, 255, 0)

# Enable for debugging of webcam settings
#controls = cam.get_controls()
#print(controls)

# Grab three frames from webcam and store the last as jpg image, we do not take the first two frames
# Do not use less frames, because the chip has to warm-up to to calculate proper exposure times!
img = cam.get_image()
img = cam.get_image()
img = cam.get_image()

#pygame.image.save(img,"./snap.jpg")
pygame.image.save(img,"/var/www/data/temp/snap.jpg")

# Stop camera
time.sleep(0.5)
cam.stop()

At the moment, I try to optimize the set_webcam() settings before and after sunrise/sunset and during daytime. An update of the script will be posted when proper conditions for all light conditions were found.

Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments