background

Niko's Project Corner

Automated image capturing + API

Description Image capture + image & video generation + API
Languages Bash
PHP
Tags GitHub
Duration Fall 2014 – Ongoing
Modified 10th April 2015
GitHub nikonyrh/webcammon
thumbnail

Out of in­ter­est on na­ture ob­ser­va­tion, com­puter vi­sion, im­age pro­cess­ing and so forth I de­vel­oped an au­to­mated sys­tem to cap­ture one photo / min­ute and store it on a disk. The pro­ject also has Bash and PHP scripts co­or­di­nat­ing ex­ter­nal tools such as mon­tage for im­age stitch­ing and men­coder for video gen­er­ation. PHP also pro­vides an HTTP API for im­age gen­er­ation and file size statis­tics.

Im­ages are cap­tured by a cron­job call­ing grabFrame.sh once a min­ute. It con­fig­ures the we­bcam be­fore each shot to use fixed pa­ram­eters for pa­ram­eters such as ex­po­sure, con­trast and color tem­per­ature to quar­an­tee more con­stant out­come. File name is based on the cur­rent UTC times­tamp to avoid prob­lems when tran­si­tion­ing in and out from the day­light sav­ing time. Con­fig­ura­tionis han­dled by call­ing V4l2-ctl and cap­ture is han­dled by fswe­bcam. Im­ages are 30 - 400 kb so one day's 1440 pho­tos take about 350 Mb, de­pend­ing on the sea­son. Ex­am­ple pho­tos from 7 am can be seen in Fig­ure 1.

7am
Figure 1: Morn­ing 7 o'clock on 15 con­sec­utive days in March shows the length­en­ing of day light du­ra­tion.

Fig­ure 1 was gen­er­ated by cre­at­ing a list of Unix epoch times­tamps which in­di­cate that at which points of time im­ages should be shown. Then ex­ist­ing im­ages are it­er­ated over and for each times­tamp the most closely match­ing im­age is re­mem­bered. The list of file names is then passed on mon­tage com­mand-line soft­ware which pro­duces the fi­nal JPG which is cached on the server. All this hap­pens by sim­ply call­ing the URL /im­age­Gen/07.jpg?grid=5 and it tiles last 25 (5 × 5) im­ages which were cap­tured at 7am.

An other time-based API call looks like /im­age­Gen/1d.jpg?w=1280&grid=8&skip=30w. It gen­er­ates a tiled 8 × 8 im­ages through­out one day 30 weeks ago, re­sult­ing in 22.5 min­utes / im­age. It should be vis­ible in GitHub at nikonyrh/we­bcam­mon/mas­ter/sam­ples/1d.jpg.

Once im­ages had been col­lected for a few days I got in­ter­ested on what kind of anal­ysis and vi­su­al­iza­tion could be done from them. An easy op­tion was to just ob­serve JPG files sizes and group them based on the date and the time of day. Since the num­ber of im­ages will be in hun­dreds of thou­sands it was nec­es­sary to make this op­er­ation fast. If the day has passed then no new pho­tos will bee added to that folder and thus file sizes can be saved on a "cache file" on disk. It is a lot faster to read a sin­gle small file than to it­er­ate over 1440 file's meta­data. The HTML based UI's vi­su­al­iza­tion of file sizes is shown in Fig­ure 2.

filesizes
Figure 2: File sizes (x 10 kb) on dif­fer­ent days and times of day at 30 min­utes res­olu­tion. Weather ef­fects such as bright sun­shine and snow­fall can clearly been de­tected by just ob­serv­ing file sizes.

The pro­ject also has an API for query­ing file size statis­tics in a plain text for­mat which can be eas­ily ex­ported to ex­ter­nal pro­grams such as Mat­lab. An ex­am­ple out­put can be seen be­low. First three columns are the year, month and day and the rest are me­dian file sizes for each hour of the day. Full rows are shown at GitHub.

    -1 -1 -1 0.00 1.00 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00 10.00 2015 03 26 52.20 32.20 31.50 31.20 42.20 53.90 176.80 380.60 402.70 389.10 374.80 2015 03 27 32.30 32.10 31.60 33.90 53.20 53.00 147.60 357.50 351.30 341.90 335.60 2015 03 28 52.70 57.90 64.50 37.60 30.60 30.60 86.80 356.20 363.00 349.70 348.90 2015 03 29 51.90 30.50 30.70 30.70 30.50 36.80 132.20 370.60 358.90 349.40 348.40 2015 03 30 31.20 31.00 30.40 30.70 30.50 30.70 100.70 315.90 293.60 267.30 255.70 2015 03 31 96.40 77.30 74.40 74.30 76.30 72.00 225.10 290.10 276.70 262.60 266.30 2015 04 01 41.40 39.00 40.60 50.50 68.50 66.30 231.00 272.90 257.70 265.40 260.30 2015 04 02 60.40 49.30 37.60 38.00 37.80 38.60 187.20 303.00 294.80 296.50 299.40 2015 04 03 31.40 31.60 31.80 31.60 31.50 32.50 217.90 359.90 340.50 334.70 338.10 2015 04 04 53.50 53.90 53.80 43.70 30.70 31.80 182.00 366.70 350.10 343.20 346.20

The fi­nal cur­rently im­ple­mented fea­ture is the par­al­lel rended­ing of videos out of se­lected im­ages, which is im­ple­mented in cre­at­eV­ideo.sh. It starts by first list­ing all de­sired im­ages' file names in the cor­rect or­der and split­ting them into four equal chunks. All of these chunks are then pro­cessed in par­al­lel (by uti­liz­ing "xargs -P0 -n1") and each pro­duces a seg­ment of the video. These seg­ments are then con­cate­nated to­gether and tem­po­rary files are deleted. The ac­tual video gen­er­ation is done by men­coder, which has rel­atively sim­ple com­mand line op­tions. One in­ter­est­ing fu­ture fea­ture would be blend­ing to­gether im­ages from dif­fer­ent sea­sons to­gether into a sin­gle high-res im­age in­stead of the cur­rently im­ple­mented tiling.


Related blog posts:

NginxBridge
AnalyticsPlatform
NoKnowledgeNotes
BenchmarkTaxiridesEsSql
CljTaxirides