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}
do
echo -n "$i "
fswebcam --save $1.jpg
sleep 2s
done
echo
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:
#!/bin/bash
OUTPUT_DIR=/var/www/webcam/`date +"%Y/%m/%d"`
OUT_FILE=`date +"%Y-%m-%d_%H:%M:%S"`
TEMP=/var/www/webcam/temp
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`
#exit
if [ `echo "$jasnosc <= $BRIGHTNESS_TRESHOLD_MIN" | bc` -eq 1 ]
then
echo -n "Brightness: $jasnosc ... too low - averaging more photos ....: "
for i in {1..5}
do
echo -n "$i "
take_photo $i "66%"
sleep 2s
done
echo
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 ]
then
echo "Brightness: $jasnosc ... too high - reducing brightness ..."
take_photo 0 "30%"
mv $TEMP/0.jpg $OUTPUT_DIR/"$OUT_FILE".jpg
else
echo "Brightness: $jasnosc : one photo is enoguh ...."
mv $TEMP/0.jpg $OUTPUT_DIR/"$OUT_FILE".jpg
fi
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: