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