We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
Page Index Toggle Pages: 1
Calculating difference of two images (Read 4022 times)
Calculating difference of two images
May 27th, 2005, 1:33am
 
Here's a little function i mashed up..
It calculates the difference between two images, as the topic says. It is fairly simple though, and i would like any comments on to how i possibly could improve any of it.

i use it to record changes to a previously taken videosnapshot.

color [] a, is videoinput.pixels, and color [] b is the image you are checking up against.
tip: if you use a singlecolored source-image, it excludes that color from the video-input.

usage in draw():
image(renderDifference(cam.pixels,img.pixels,10),0,0);

Code:
 
PGraphics3 renderDifference(color [] a, color [] b, float sens)
{
PGraphics3 tmp = new PGraphics3(width,height,null);
color trans = color(0,255,0); // the color of the pixels that haven't changed
for(int i = 0; i < width; i++)
{
for(int j = 0; j < height; j++)
{
float rA = red(a[j*width+i]);
float gA = green(a[j*width+i]);
float bA = blue(a[j*width+i]);
float rB = red(b[j*width+i]);
float gB = green(b[j*width+i]);
float bB = blue(b[j*width+i]);
boolean changed = false;

// RED
if((rA>(rB+sens)) || ((rA+sens)<rB)) changed = true;

// GREEN
if((gA>(gB+sens)) || ((gA+sens)<gB)) changed = true;

// BLUE
if((bA>(bB+sens)) || ((bA+sens)<bB)) changed = true;

if(changed)
tmp.pixels[j*width+i] = a[j*width+i];
else
tmp.pixels[j*width+i] = trans;
}
}
return tmp;
}

void mousePressed()
{
color c = Scamera.pixels[mouseY*width+mouseX];
// get the current color under mouse
// for setting single-colored source images
// # add some function to color source image
}



-seltar
Re: Calculating difference of two images
Reply #1 - May 27th, 2005, 1:06pm
 
you might try using HSB colorspace instead of RGB; you would only need to test one value, hue or brightness, instead of 3
Re: Calculating difference of two images
Reply #2 - May 29th, 2005, 2:00am
 
A speedier method would be trim those floats to ints using a trick I learned from the seniors:
Code:

for (int iy = 0; iy < img1.height; iy++){
for (int ix = 0; ix < img1.width; ix++){
color c1 = img1.pixels[ix + iy * img1.width];
color c2 = img2.pixels[ix + iy * img2.width];
int r1=c1>>16&0xff;
int g1=c1>>8&0xff;
int b1=c1&0xff;
int r2=c2>>16&0xff;
int g2=c2>>8&0xff;
int b2=c2&0xff;
display.pixels[ix + iy * display.width] = color (abs(r1-r2),abs(g1-g2),abs(b1-b2));
}
}

And I got a nice brightness value reader off of Fry:
Code:

int gray(color p) {
return max((p >> 16) & 0xff, (p >> 8) & 0xff, p & 0xff);
}

Handy stuff I'm still using.
Re: Calculating difference of two images
Reply #3 - May 31st, 2005, 10:13am
 
As the size of the camera image is usually the same size as the canvas, there is a lot of optimizations you can apply - get rid of all those multiplications in the first place.

The second, much bigger optimization is to use bitwise XOR (^) instead of abs(a-b) - it also makes the extraction of the rgb values obsolete:

Code:

function dif(int[] img){
  for (int i=pixels.length;--i>-1;pixels[i]^=img[i]){}
}

function imgDif(int[] img1,int[] img2){
  for (int i=pixels.length;--i>-1;pixels[i]=img1[i]^img2[i]){}
}

Re: Calculating difference of two images
Reply #4 - May 31st, 2005, 10:44am
 
and maybe
if((rA>(rB+sens)) || ((rA+sens)<rB)) changed = true;
should be

if (sens > abs(rA-rB))  changed = true;


seems cleaner and probably a little faster
Re: Calculating difference of two images
Reply #5 - May 31st, 2005, 10:59am
 
BTW, I'm new to this, and new to java for that matter, so I don't get this PGraphics stuff. From what I could find I understand it's better engine then the normal loadpixels / pixels because it deals with a buffer, or something like that, but I'm lacking in syntax.

So, could you post a little more code (or all of it ? Cheesy ) because I don't understand where should I get color[]b from. I tried initialising it to a white image, but that just turned the screen green, allthough color[]a is the camera image.

And I think there should be a color[]b =color[]a at the end somewhere, but that's another thing.

And I'd really like to see this thing, because I built my own camera difference thingie and it's a little slow, so if I'm gaining performance, I want in Smiley


Code:

import processing.video.*;
Capture cam;
PImage img;

color c;
int camW = 320;
int camH = 240;

void setup(){
size(camW,camH);
fill(255,0,0);
String s = Capture.list()[0];
cam = new Capture(this, s, camW,camH);
img = new PImage(width,height);
for (int i=0;i<width*height; i++){
img.pixels[i] = color(0,0,0);
}
}



void draw(){
image(renderDifference(cam.pixels,img.pixels,10),0,0);
}


That's it, and the other file is your renderDifference function
Re: Calculating difference of two images
Reply #6 - May 31st, 2005, 2:54pm
 
check out http://seltar.wliia.org .. rewritten the webcam functions to image so they'll work on web.. with sources.. color [] b is just an image.pixels ..
the way i use it is..
color [] a = myCamera.pixels
color [] b = mySourceImage.pixels
and it calculates the difference between the two..
so it sortof looks like a greenscreen.. i've added a color [] c, for video-background.. but that's another thing..

hope you figure out what you need..if not, please post again.. i'll be glad to help you out

-seltar
Re: Calculating difference of two images
Reply #7 - May 31st, 2005, 4:21pm
 
Thenk you sir, it worked. Now the cam is visible under the top image's mask. Now I gotta explre more to see what this PGraphics3 is all about.
Re: Calculating difference of two images
Reply #8 - Jun 2nd, 2005, 7:02pm
 
The next step. I have this code:

Code:

import processing.video.*;
PImage img, oldCam;
Capture cam;

boolean src = false, shiftdown = false;
int sens = 70;
int[] ax,ay;
int num = 0;

void setup(){
size(320, 240, P3D);
framerate(20);
String s = Capture.list()[0];
cam = new Capture(this, s, 320, 240, 30);

img = loadImage("a.jpg");
oldCam = img;
}

void draw(){
image(renderDifference(cam.pixels, oldCam.pixels, sens),0,0);
}



void captureEvent(Capture camera) {
cam.read();
}





PGraphics3 renderDifference(color[] a, color[] b, int sens){
PGraphics3 tmp = new PGraphics3(width,height,null);
color trans = color(255,255,255); //the colour of the pixels w/ movement
color ch = color(0,0,0); //the colour of the pixels that haven't changed

for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++){
float bA = brightness(a[j*width+i]);
float bB = brightness(b[j*width+i]);

if (sens<abs(bA-bB)) tmp.pixels[j*width+i] = ch;
else tmp.pixels[j*width+i] = trans;
}
}

for (int i=0;i<width*height;i++) oldCam.pixels[i] = cam.pixels[i];
return tmp;
}



The problem with it is that it flickers, it looks like a 1/1 flicker (one frame's ok, the other one is missing or something) and I'm not sure if it's from the code or not.
My camera seems pretty noisy, maybe that's it ...
OR, it just looks like flicker because it happends fast, I don't know, can't tell.  Does it flicker for you too ?

If it's from the code  guess I could implement something like a blending, although for what I want I don't think it's needed ... I'll have to think about that later.

...
And what's with those lines ... any idea ?
Re: Calculating difference of two images
Reply #9 - Jun 2nd, 2005, 7:17pm
 
well, those lines are probably linked to what the a.jpg contains i guess..

this stopped the flickering for me:
(i used new PImage instead of loading an image..)
Code:


img = new PImage(width,height);
oldCam = img;
}

void draw(){
image(renderDifference(cam.pixels, oldCam.pixels, sens),0,0);
}

void captureEvent(Capture cam) {
cam.read();
}

PGraphics3 renderDifference(color[] a, color[] b, int sens){
PGraphics3 tmp = new PGraphics3(width,height,null);
color trans = color(255,255,255); //the colour of the pixels w/ movement
color ch = color(0,0,0); //the colour of the pixels that haven't changed

for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++){
float bA = brightness(a[j*width+i]);
float bB = brightness(b[j*width+i]);

if (sens<abs(bA-bB)) tmp.pixels[j*width+i] = ch;
else tmp.pixels[j*width+i] = trans;
oldCam.pixels[i] = cam.pixels[i];
}
}
return tmp;
}
Re: Calculating difference of two images
Reply #10 - Jun 3rd, 2005, 10:33pm
 
Quasimondo wrote on May 31st, 2005, 10:13am:
The second, much bigger optimization is to use bitwise XOR (^) instead of abs(a-b) - it also makes the extraction of the rgb values obsolete

Damn that's tasty. I'm still trying to comprehend bitwisdom. You learn something new everyday.
Page Index Toggle Pages: 1