I was reading this and this paper about hand/head tracking. They both talk about detecting motion computing the difference in a neighborhood of each pixel and comparing the result with a threshold:
Quoting from the first paper:
We use the temporal differencing method described in Ref. [41], which computes the absolute value of differences in the neighborhood surrounding each pixel, and then derive the accumulated differ- ence by summing the difference of all neighboring pixels. When the accumulated difference is above a predetermined thresh- old, the pixel is assigned to the moving region.
Is there an efficient way to do it (possibly in OpenCV)?
The code I wrote is pretty naive and, besides losing the real-time, seems not to give better results than a simpler pixel-to-pixel difference:
template<class T> class Image {
private:
IplImage* imgp;
public:
Image(IplImage* img=0) {imgp=img;}
~Image(){imgp=0;}
void operator=(IplImage* img) {imgp=img;}
inline T* operator[](const int rowIndx) {
return ((T *)(imgp->imageData + rowIndx*imgp->widthStep));}
};
typedef Image<unsigned char> BwImage;
typedef Image<float> BwImageFloat;
void computeMovingRegion( IplImage* prev, IplImage* cur, IplImage *mov) {
BwImage _prev(prev);
BwImage _cur(cur);
BwImage _mov(mov);
for (int i = 3; i<prev->height-3; i++) {
for (int j=3; j<prev->width-3; j++) {
int res=0;
for (int k=i-3; k<i+3; k++)
for (int n=j-3; n<j+3; n++)
res += abs(_cur[k][n] -_prev[k][n]);
if (res>2000) {
_mov[i][j]=_cur[i][j];
}
else
_mov[i][j]=0;
}
}
}
Images are in grayscale. Don’t think it matters, but I’m using MacOS 10.8 and Xcode 4.4.2.
You should be able remove a lot of the redundancy if you first calculate the absolute difference image (i.e.
abs(_cur[] - prev[])) and then just iterate over this. There are a lot more optimisations you can do beyond this, but this would be a good start for relatively little effort.Also note that your loop indexing looks wrong – if you want to do a 7×7 neighbourhood operation it should be: