sobota, 6 kwietnia 2013

Enhance night images from webcam

Night images taken by cheap webcams are usually blurry, pixelized and low quality:

But the quality of final image can be enhanced by averaging multiple subsequent expositions. Here is simple bash script. All we need is:program which takes photo by your webcam (here I use fswebcam) and convert from ImageMagick suite. Both available in repositories of main linux distributions.

    for i in {1..5}
    echo -n "$i "
    fswebcam --save $1.jpg

    sleep 2s

    echo "Averaging...."
    convert *.jpg -evaluate-sequence mean averaged.jpg

This script takes five photos, with two seconds pauses, a nd then "averages" those photos to eliminate artifacts. Here is "averaged" image:

As we can see, the quality is better than before. Good. But next problem is: we would like to perform such averaging only for dark images (images taken in good light conditions are acceptable quality).

Checking image brightness

Simple metod to asses brightness of image. By issuing command:

convert 0.jpg -colorspace hsb  -resize 1x1  txt:-

we gets some information, including "brightness":

# ImageMagick pixel enumeration: 1,1,255,hsb
0,0: (154,193,  1)  #9AC101  hsb(60.441%,75.8801%,0.488289%)

here 0.488289% is brightness.

To get the value, we use some bash tricks:

convert 0.jpg -colorspace hsb  -resize 1x1  txt:- | \
sed 1d | tr '()%' ' ' | awk -F "," '{print $6}'

then we can make some conditional if to check if image brightness is acceptable or low - in this case we will perform averaging. The script could look like:


OUTPUT_DIR=/var/www/webcam/`date +"%Y/%m/%d"`
OUT_FILE=`date +"%Y-%m-%d_%H:%M:%S"`

BRIGHTNESS_TRESHOLD_MIN=10      # for too dark images
BRIGHTNESS_TRESHOLD_MAX=60      # for too bright images

mkdir -p $OUTPUT_DIR
mkdir -p $TEMP

function take_photo {
fswebcam  -S 32 --jpeg 65 \
        -r 640x480 \
        --banner-colour "#35000000" --line-colour "#35000000" \
        --timestamp "%Y-%m-%d %H:%M (%Z)" \
        --set lights=off \
        --set "White Balance Temperature, Auto"=True \
        --set brightness=$2  \
        -q \
        --set "Saturation"=58 \
        --save $TEMP/$1.jpg

echo ------------------------ first photo -------------

take_photo 0 "50%"

jasnosc=`convert $TEMP/0.jpg -colorspace hsb  -resize 1x1  txt:- | \
sed 1d | tr '()%' ' ' | awk -F "," '{print $6}'`

#echo `echo "$jasnosc <= $BRIGHTNESS_TRESHOLD" | bc`

if [ `echo "$jasnosc <= $BRIGHTNESS_TRESHOLD_MIN" | bc` -eq 1 ]
    echo -n "Brightness: $jasnosc ... too low - averaging more photos ....: "
    for i in {1..5}
    echo -n "$i "
    take_photo $i "66%"
        sleep 2s


   echo "Averaging...."
    cd $TEMP
    convert *.jpg -evaluate-sequence mean averaged.jpg
    mv averaged.jpg $OUTPUT_DIR/"$OUT_FILE".jpg
    rm *

elif [ `echo "$jasnosc >= $BRIGHTNESS_TRESHOLD_MAX" | bc` -eq 1 ]
    echo "Brightness: $jasnosc ... too high - reducing brightness  ..."
    take_photo 0 "30%"
    mv $TEMP/0.jpg $OUTPUT_DIR/"$OUT_FILE".jpg

    echo "Brightness: $jasnosc :  one photo is enoguh ...."
    mv $TEMP/0.jpg $OUTPUT_DIR/"$OUT_FILE".jpg

tehere is another elseif: if image is too bright, we are taking another one with reduced brightness.

Additional features

We can log the calculated brightness and then make a nice plot of this relative brightness during days:

1 komentarz: