#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/extensions/XTest.h>
#define WIDTH 640
#define HEIGHT 480
#define SEARCHRANGE 100
#define STATE_UP 0
#define STATE_DOWN 1
#define CHANGE_NONE 0
#define CHANGE_SHRINKING 1
#define CHANGE_GROWING 2
#define CHANGEFACTOR .75
int searchx = -1;
int searchy = -1;
int startw = 100;
int starth = 100;
int lasth = 100;
int lastw = 100;
int shapechange = CHANGE_NONE;
CvPoint topleft;
CvPoint bottomright;
int state;
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 rowIndex) {
return ((T*)(imgp->imageData + rowIndex*imgp->widthStep));
}
};
typedef struct {
unsigned char b,g,r;
} RgbPixel;
typedef struct {
float b,g,r;
} RgbPixelFloat;
typedef Image<RgbPixel> RgbImage;
void on_mouse( int event, int x, int y, int flags, void* param )
{
}
void paint_red (IplImage *frame, Display *dpy) {
int xmin, xmax, ymin, ymax;
int top = HEIGHT, bottom = -1, left = WIDTH, right = -1;
if (searchx == -1 || searchy == -1) {
xmin = 0;
ymin = 0;
xmax = WIDTH;
ymax = HEIGHT;
} else {
xmin = MAX (0, searchx - SEARCHRANGE);
xmax = MIN (WIDTH, searchx + SEARCHRANGE);
ymin = MAX (0, searchy - SEARCHRANGE);
ymax = MIN (HEIGHT, searchy + SEARCHRANGE);
}
RgbImage image (frame);
int redxt = 0, redyt = 0;
int count = 0;
for (int i = ymin; i < ymax; i++) {
for (int j = xmin; j < xmax; j++) {
int r = image[i][j].r;
int g = image[i][j].g;
int b = image[i][j].b;
if (g < 0x20 && b < 0x20 && r > 0x80) {
image[i][j].r=0xFF;
image[i][j].g=0x00;
image[i][j].b=0x00;
redyt += i;
redxt += j;
count++;
top = MIN (top, i);
bottom = MAX (bottom, i);
left = MIN (left, j);
right = MAX (right, j);
}
}}
if (count) {
searchx = redxt / count;
searchy = redyt / count;
float redx = (float) redxt / count / WIDTH;
float redy = (float) redyt / count / HEIGHT;
int screenx = (int)(redx * 1480.0 - 100);
int screeny = (int)(redy * 1000.0 - 100);
XTestFakeMotionEvent (dpy, DefaultScreen (dpy), screenx, screeny, 0);
//boundingbox = cvRect (top, bottom, left, right);
topleft = cvPoint (left, top);
bottomright = cvPoint (right, bottom);
int thish = bottom - top;
int thisw = right - left;
if (shapechange && abs(lasth - thish) < lasth * 1 - CHANGEFACTOR) {
if (shapechange == CHANGE_GROWING)
state = STATE_UP;
else
state = STATE_DOWN;
}
if (thish < lasth * CHANGEFACTOR) shapechange = CHANGE_SHRINKING;
else if (thish * CHANGEFACTOR > lasth) shapechange = CHANGE_GROWING;
else shapechange = CHANGE_NONE;
lasth = thish;
lastw = thisw;
XFlush (dpy);
} else {
searchx = -1;
searchy = -1;
}
}
int main( int argc, char** argv )
{
Display *dpy = XOpenDisplay (0);
CvCapture* capture = cvCaptureFromCAM(0);
IplImage *frame = 0;
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, WIDTH);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, HEIGHT);
if( !capture )
{
fprintf(stderr,"Could not initialize capturing...\n");
return -1;
}
cvNamedWindow( "CamShiftDemo", 1 );
cvSetMouseCallback( "CamShiftDemo", on_mouse, 0 );
frame = cvQueryFrame( capture );
int step = frame->widthStep / sizeof (uchar);
for(;;)
{
frame = cvQueryFrame( capture );
if( !frame )
break;
cvFlip (frame, 0, 1);
paint_red (frame, dpy);
cvRectangle (frame, topleft, bottomright, cvScalar(255,255,255), 3-4*state, 8, 0);
cvShowImage ("CamShiftDemo", frame);
char c = cvWaitKey(10);
}
cvReleaseCapture( &capture );
cvDestroyWindow("CamShiftDemo");
return 0;
}