package demo;
import static com.googlecode.javacv.jna.cv.CV_BGR2GRAY;
import static com.googlecode.javacv.jna.cv.cvCalcOpticalFlowPyrLK;
import static com.googlecode.javacv.jna.cv.cvCvtColor;
import static com.googlecode.javacv.jna.cv.cvFindCornerSubPix;
import static com.googlecode.javacv.jna.cv.cvGoodFeaturesToTrack;
import static com.googlecode.javacv.jna.cxcore.CV_RGB;
import static com.googlecode.javacv.jna.cxcore.CV_TERMCRIT_EPS;
import static com.googlecode.javacv.jna.cxcore.CV_TERMCRIT_ITER;
import static com.googlecode.javacv.jna.cxcore.cvCircle;
import static com.googlecode.javacv.jna.cxcore.cvCopy;
import static com.googlecode.javacv.jna.cxcore.cvCreateImage;
import static com.googlecode.javacv.jna.cxcore.cvGetSize;
import static com.googlecode.javacv.jna.cxcore.cvPoint;
import static com.googlecode.javacv.jna.cxcore.cvReleaseImage;
import static com.googlecode.javacv.jna.cxcore.cvSize;
import static com.googlecode.javacv.jna.cxcore.cvTermCriteria;
import org.nyu.mocap.anmotion.java.RemoteVideoCapture;
import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.jna.cv;
import com.googlecode.javacv.jna.cxcore.CvPoint2D32f;
import com.googlecode.javacv.jna.cxcore.IplImage;
import com.sun.jna.ptr.IntByReference;
public class OpticalFlow2 extends Thread {
public static final int MAX_COUNT =500;
public static final int MIN_COUNT = 10;
private IplImage image,grey,preGrey,pyramid,prePyramid,swapTemp;
private CvPoint2D32f[] currentPoints;
private CvPoint2D32f[] previousPoints;
private CvPoint2D32f[] swapPoints;
private byte[] status;
private boolean needToInit;
private IntByReference count;
private int winSize = 10;
private int flags;
private int movementX;
private int movementY;
private CanvasFrame canvasFrame;
private RemoteVideoCapture capture;
private boolean fromPC = true;
private OpenCVFrameGrabber grabber;
public OpticalFlow2(RemoteVideoCapture capture){
this.capture = capture;
fromPC = false;
}
public OpticalFlow2(OpenCVFrameGrabber grabber){
this.grabber = grabber;
fromPC = true;
}
@Override
public void run(){
canvasFrame = new CanvasFrame("Optical Flow");
count = new IntByReference();
needToInit = true;
if(fromPC){
try {
grabber.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
while(true){
int i,k,c;
//grab current frame
IplImage frame=null;
if(fromPC){
try {
frame = grabber.grab();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
frame = capture.grab();
}
if(frame==null)
return;
if(image==null){
//create images;
image = cvCreateImage(cvGetSize(frame),8,3);
image.origin = frame.origin;
grey = cvCreateImage(cvGetSize(frame),8,1);
preGrey = cvCreateImage(cvGetSize(frame),8,1);
pyramid = cvCreateImage(cvGetSize(frame),8,1);
prePyramid = cvCreateImage(cvGetSize(frame),8,1);
currentPoints = CvPoint2D32f.createArray(MAX_COUNT);
previousPoints = CvPoint2D32f.createArray(MAX_COUNT);
status = new byte[MAX_COUNT];
flags = 0;
System.out.println("create image finished.");
}
cvCopy(frame,image,null);
cvCvtColor(image,grey,CV_BGR2GRAY);
if(needToInit){
IplImage eig = cvCreateImage(cvGetSize(grey),32,1);
IplImage temp = cvCreateImage(cvGetSize(grey),32,1);
double quality = 0.2;
double minDistance = 10;
count.setValue(MAX_COUNT);
cvGoodFeaturesToTrack( grey, eig, temp, currentPoints, count,
quality, minDistance, null, 3, 0, 0.04 );
cvFindCornerSubPix( grey, currentPoints, count.getValue(),
cvSize(winSize,winSize), cvSize(-1,-1),
cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));
cvReleaseImage( eig.pointerByReference() );
cvReleaseImage( temp.pointerByReference() );
System.out.println("init features finished.");
}else if(count.getValue()>0){
cvCalcOpticalFlowPyrLK( preGrey, grey, prePyramid, pyramid,
previousPoints, currentPoints, count.getValue(), cvSize(winSize,winSize), 3, status,(float[]) null,
cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03), flags );
flags |= cv.CV_LKFLOW_PYR_A_READY;
movementX = 0;
movementY = 0;
for( i = k = 0; i < count.getValue(); i++ )
{
if( status[i]==(byte)0)
continue;
currentPoints[k++]=currentPoints[i];
cvCircle( image, cvPoint((int)currentPoints[i].x,(int)currentPoints[i].y), 3, CV_RGB(0,255,0), -1, 8,0);
//calculate movement
movementX+=(int)(currentPoints[i].x-previousPoints[i].x);
movementY+=(int)(currentPoints[i].y-previousPoints[i].y);
}
System.out.println("movementX:"+movementX+",movementY:"+movementY);
count.setValue(k);
System.out.println("calculate finished. features left:"+count.getValue());
}
//swap images
swapTemp = preGrey;
preGrey = grey;
grey = swapTemp;
swapTemp = prePyramid;
prePyramid = pyramid;
prePyramid = swapTemp;
//swap points;
swapPoints = currentPoints;
currentPoints = previousPoints;
previousPoints = swapPoints;
needToInit = false;
if(count.getValue()<MIN_COUNT){
needToInit = true;
}
}
}
public static void main(String[] args){
OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
OpticalFlow2 of = new OpticalFlow2(grabber);
of.start();
}
public void updateImage(){
if(image!=null)
canvasFrame.showImage(image);
}
}
|