0

I'm trying to find the most lightweight method to detect "adequate" change in an image. I realize that's a terrible constraint, so for the sake of this question I'll break it into two different qualifiers: substantial change, or 80% pixels changed, and motion-changed, or 10% pixels changed. These images are captured via timelapse mode on a raspberry pi camera, but for the sake of the question, the files could be from any basically-static view point.

I've found that I can use filesize to observe change of substantial amounts:

user@host-bb:/tmp$ ls -la investigating/
total 134604
drwxr-xr-x 2 user group    4096 Oct 20 00:05 .
drwxr-xr-x 5 user group    4096 Oct 20 00:04 ..
-rw-r--r-- 1 user group 4580181 Oct 20 00:05 image1018223300.jpg
-rw-r--r-- 1 user group 4573449 Oct 20 00:05 image1018223301.jpg
-rw-r--r-- 1 user group 4573024 Oct 20 00:05 image1018223304.jpg
...snip...
-rw-r--r-- 1 user group 4455867 Oct 20 00:05 image1018223320.jpg
-rw-r--r-- 1 user group 4447607 Oct 20 00:05 image1018223321.jpg
-rw-r--r-- 1 user group 4434839 Oct 20 00:05 image1018223323.jpg
-rw-r--r-- 1 user group 4416942 Oct 20 00:05 image1018223324.jpg
-rw-r--r-- 1 user group 1769008 Oct 20 00:05 image1018223325.jpg
-rw-r--r-- 1 user group 1702851 Oct 20 00:05 image1018223326.jpg
-rw-r--r-- 1 user group 1639306 Oct 20 00:05 image1018223327.jpg
-rw-r--r-- 1 user group 1788435 Oct 20 00:05 image1018223328.jpg
-rw-r--r-- 1 user group 1908061 Oct 20 00:05 image1018223329.jpg
-rw-r--r-- 1 user group 1981029 Oct 20 00:05 image1018223330.jpg
-rw-r--r-- 1 user group 2102390 Oct 20 00:05 image1018223331.jpg
-rw-r--r-- 1 user group 2167734 Oct 20 00:05 image1018223333.jpg
-rw-r--r-- 1 user group 2243082 Oct 20 00:05 image1018223334.jpg
...snip...
-rw-r--r-- 1 user group 2640732 Oct 20 00:05 image1018223342.jpg
-rw-r--r-- 1 user group 2730206 Oct 20 00:05 image1018223343.jpg
-rw-r--r-- 1 user group 2751966 Oct 20 00:05 image1018223344.jpg
-rw-r--r-- 1 user group  315875 Oct 20 00:05 image1018223345.jpg
-rw-r--r-- 1 user group  302476 Oct 20 00:05 image1018223352.jpg
...snip...
-rw-r--r-- 1 user group  285965 Oct 20 00:05 image1018223358.jpg
-rw-r--r-- 1 user group  289271 Oct 20 00:05 image1018223359.jpg
user@host-bb:/tmp$ 

Even between somewhat non-major changes in lighting (such as occurred between images *28.jpg and *29.jpg) can produce a difference in filesize.
I realize this is basically binning, and it could be the solution I'm looking for.
This takes care of the "substantial change" (80% of pixels changed).

The question remains though: Short of Imagemagick, Python script, or other image processing software, is there a lightweight way to detect change in an image that is closer to 10% pixels changed? If there is no non-image-processing software option, what would the most light-weight option be? Writing my own processing in a low-level language? A Python script? I'm coming from a Python background and am trying to do simple change detection on a raspberry pi zero w that can then trigger an event (file upload) if there is a change. Bandwidth is too small to send all the images, and the pi zero w is not a heavy hitter when it comes to processing power.

4
  • You'd also need to take into account the amount of change for each pixel. The noise from the camera might make even back-to-back images differ significantly if you only look at the number of changed pixels
    – ilkkachu
    Oct 20, 2019 at 12:38
  • @ilkkachu That is true; I'm not saying that the size comparison is a good detector, just that it's a simple one I've found may somewhat work in some cases... Oct 20, 2019 at 13:24
  • No, the size difference is definitely an indicator of some change, but not a very discreet one of course. What I meant is that when you said you'd like to detect e.g. 10 % of the pixels changing to detect motion, it's not enough to just detect the change, you have to check the magnitude too. And the image size might be too rough an indicator to help there, if the lighting and such remain the same.
    – ilkkachu
    Oct 20, 2019 at 13:59
  • I think Python has some image processing libraries, so it shouldn't be too hard to just make a program to look at the pixels. You seem to have something like 1 image per second, so performance shouldn't be an issue. I mean, I'm not sure, but I doubt even the Pi zero is that slow...
    – ilkkachu
    Oct 20, 2019 at 13:59

1 Answer 1

2

1) Very very basic (but very lightweight): using cmp and to compare the files byte by byte ("binary diff"). Gives the amount of different bytes. I just tried on a zero, works.

cmp -l 1.jpg 2.jpg 2>/dev/null | wc -l

but, it's more file related than image-wise...

Therefore, if you have access to Python on your machine (sorry I don't have the same distribution on my rpi zero so I can't test...):

2) SSIM-PIL Python package, based on Structural SIMilarity. (https://pypi.org/project/SSIM-PIL/). Is image oriented so compared to solution one, it should give less "false differences", meaning the result will be closer to what the human eye sees. https://fr.wikipedia.org/wiki/Structural_Similarity

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .