Android Question Detect change or difference in a part of an image

Spanish

New Member
Licensed User
Longtime User
Hi friends!

Excuse my bad English, I'm helping myself with a translator.

I've been working with B4X for a while and I love it, but I haven't found anything on the forum to help me with this problem.

I need to detect a change in a part of an image.

I'll explain.

The app will take a first photo and the user must choose which part of the photo the app should monitor and alert if a change occurs. Something like a rectangle (x1, y1, x2, y2).

Then the app will take a photo every minute and then you will have to decide if there were changes in the part of the image that the user indicated.

I don't have anything created because I'm still researching, but I had thought of using the Bitmap.GetPixel function to compare exactly the pixels that are in the box that the user indicated, and if, for example, it's 50% different, it would tell the user there that a change happened.

What do you think? I imagine there are better ideas.

I don't know if with Google Mobile Vision or with the OpenCV320 library you can make it easier, but I don't know how to use them.

I attached some images to them so they can more or less understand what I need.

Again, excuse my bad English!

IMG1.jpg
IMG2.jpg
 

JordiCP

Expert
Licensed User
Longtime User
Hi,

The main difficulty here is to decide 'what is a change', in terms of color, lightness, size, shape... for instance, if more than 30% of the pixels in the selected zone have a variation in lightness (or basic color) above a certain percentage, then this would be a criteria to start with a 'change detection' algorithm.
The more you know about the expected change, the more smart your algorithm will be (for instance, if the background color is red and the object that can appear is blue, just as an example...)

Also, the algorithm/setup must take into account some obvious things such as:
  • Camera must be totally static, otherwise pixels will be different because of small displacements.
  • There is always some random noise in the pixels, so two pictures taken with a 1 minute interval may not be equal even if nothing has changed
  • External light conditions can also change the captured pixels, even if they are not noticed to the human eye.

Taking this into account, if you only need to do it every minute, it can still be done with GetPixel, or using OpenCV. The later has a bit of learning curve but has some primitives that allow to build and execute such algorithms (once the criteria are defined) easily.
 
Upvote 0

Spanish

New Member
Licensed User
Longtime User
Hi JordiCP, thank you for responding so quickly.

Yes, the device must be fixed, without moving, in a tripod or something similar.

For now I need it to detect if a light bulb has been turned on, as shown in the image above. That is why you don't need to analyze the whole image, just the small part where the bulb comes out.

I suppose you could check if any amount of pixels of white tones have appeared in that part of the image? right where the light bulb is? Of course, the user must indicate a box where exactly the bulb is displayed.

Also as you say, there are some conditions that could affect the algorithm, such as the light condition or noise, but I suppose you could give the user an option like "precision type: High, Medium, Low", and based on that will be the percentage will be the percentage changes that have been presented.

If the user has perfect conditions, he or she can use the "Precision: High" or something.
 
Upvote 0

JordiCP

Expert
Licensed User
Longtime User
I suppose you could check if any amount of pixels of white tones have appeared in that part of the image? right where the light bulb is? Of course, the user must indicate a box where exactly the bulb is displayed.

Yes, in this case I would calculate the lightness of each pixel.

It can be roughly approached by lightness=0.25*RED+0.5*GREEN+0.25*BLUE
(or, if the light is reddish, just take the Red channel)

Then, count the pixels in the selected window for which the ligthness difference is above a certain threshold. Calculating the percentage (counted_pixels/total_pixels) and analysing it for different threshold levels using pairs of pictures (bulb off/on) can help to decide which are the optimum values (lightness difference threshold and percentage)
 
Upvote 0

Spanish

New Member
Licensed User
Longtime User
Ok. I'll try to create my code with these recommendations and then you'll tell me if I'm going well. Thank you very much in advance!
 
Upvote 0

emexes

Expert
Licensed User
Yes, in this case I would calculate the lightness of each pixel.
A more general approach is to have a reference image, and then subtract it from the current image and trigger on a change > threshold within the detection area(s).

The reference and compared images can usually be of reduced-size/resolution, eg a 192 x 108 image (or some other convenient scaling) will often be sufficient, and quicker too (bonus!).
It can be roughly approached by lightness=0.25*RED+0.5*GREEN+0.25*BLUE
True, but that won't detect things like eg: a 40% red object moving against a 20% green background. I usually just use the sum of absolute differences eg:

Change = Abs(Red - RedRef) + Abs(Green - GreenRef) + Abs(Blue - BlueRef) 'returns values 0..765, not 0..255

A more correct version would be done with squares and a square-root, but this adds a lot of clock cycles for little gain.

If the camera is not fixed, and the light can appear in different locations within the frame, then post #4 is probably a better approach, eg, define a light as being "at least n "light" pixels within an x-by-y rectangle, where "light" is eg within error c of a reference light pixel RGB value, or within an RrBbGg cube.
 
Upvote 0
Top