JavaCV:使用Camshift算法跟踪对象

时间:2013-07-17 11:31:26

标签: opencv tracking javacv

我想使用Camshift算法跟踪对象。我试图纠正我在原始OpenCV Camshift文件的JavaCV转换中发现的错误。

这是我的代码:

package objectTracking;

import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.FrameGrabber;
import com.googlecode.javacv.OpenCVFrameGrabber;
import static com.googlecode.javacv.cpp.opencv_core.*;
import com.googlecode.javacv.cpp.opencv_core.CvBox2D;
import com.googlecode.javacv.cpp.opencv_core.CvPoint;
import com.googlecode.javacv.cpp.opencv_core.CvRect;
import com.googlecode.javacv.cpp.opencv_core.CvScalar;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import com.googlecode.javacv.cpp.opencv_core.IplImageArray;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import com.googlecode.javacv.cpp.opencv_imgproc.CvConnectedComp;
import com.googlecode.javacv.cpp.opencv_imgproc.CvHistogram;
import static com.googlecode.javacv.cpp.opencv_video.*;
import com.sun.jna.ptr.FloatByReference;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class CamShifter implements MouseListener{
final static int MOUSE_PRESSED = 1;
final static int MOUSE_RELEASED = 2;

    IplImage image, frame, hsv, hue, mask, backproject, histimg;
    IplImageArray hueArray;
    CvHistogram hist;
    CanvasFrame histogram = new CanvasFrame("Histogram"), camshiftDemo = new CanvasFrame("CamshiftDemo");

    boolean backproject_mode = false;
    boolean select_object = false;
    int track_object = 0;
    boolean show_hist = true;

    boolean paused = false;

    CvPoint origin = new CvPoint();
    CvRect selection = new CvRect();

    OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
    CvRect track_window = new CvRect();
    CvBox2D track_box = new CvBox2D();

    CvConnectedComp track_comp = new CvConnectedComp();

    int hsize = 16;
    float hranges[] = {0,180};
    int[] hdims = {hsize};
    float hranges_arr[][] = {hranges};

    int vmin = 10, vmax = 256, smin = 30;

    public static void main(String args[]) throws  Exception  {

        CamShifter csh = new CamShifter();
        csh.work(csh);
        System.out.println("CamShiftDetector trial");


    }

    public CamShifter() throws FrameGrabber.Exception {

        grabber.start();
        camshiftDemo.getCanvas().addMouseListener(this);

    }


    public void onMouse(int event, int x, int y) {
        if (select_object) {
            //get selection
            int selX, selY, selW, selH;
            selX = Math.min(x, origin.x());
            selY = Math.min(y, origin.y());
            selW = selX + Math.abs(x - origin.x());
            selH = selY + Math.abs(y - origin.y());
            selection = cvRect(selX, selY, selW, selH);
            System.out.println("Selection : \n("+selX+", "+selY+")\n("+selW+", "+selH+")");

            //ensure that selection is enclosed within the image
            selX = Math.max(selection.x(), 0);
            selY = Math.max(selection.y(), 0);
            selW = Math.min(selection.width(), image.width());
            selH = Math.min(selection.height(), image.height());
            selection = cvRect(selX, selY, selW - selX, selH - selY);
            System.out.println("ensure that selection is enclosed within the image");
            System.out.println("Selection : \n("+selX+", "+selY+")\n("+selW+", "+selH+")");
        }

        switch (event) {
            case MOUSE_PRESSED: 
                origin = cvPoint(x, y);
                selection = cvRect(x, y, 0, 0);
                select_object = true;
                break;
            case MOUSE_RELEASED: 
                select_object = false;
                if (selection.width() > 0 && selection.height() > 0) {
                    track_object = -1;
                }
                break;
        }
    }


    CvScalar hsv2rgb(float hue) {
        int[] rgb = new int[3];
        int p, sector;
        int[][] sector_data = {{0, 2, 1}, {1, 2, 0}, {1, 0, 2}, {2, 0, 1}, {2, 1, 0}, {0, 1, 2}};
        hue *= 0.033333333333333333333333333333333f;
        sector = (int) Math.floor(hue);
        p = Math.round(255 * (hue - sector));
        p = p ^ 1;
        int temp = 0;
        if ((sector & 1) == 1) {
            temp = 255;
        } else {
            temp = 0;
        }
        p ^= temp;

        rgb[sector_data[sector][0]] = 255;
        rgb[sector_data[sector][1]] = 0;
        rgb[sector_data[sector][2]] = p;

        return cvScalar(rgb[2], rgb[1], rgb[0], 0);
    }

    String coffee;
    public void work(CamShifter csh) throws Exception {
        IplImage capture = grabber.grab();

        System.out.println("paused = "+paused);
        if (capture == null) {
            System.out.println("Could not initialize capturing...\n");
            return;
        }

        while (true) {
            int bin_w;
            if (!paused) {
                frame = grabber.grab();
                if (frame == null) {
                return;
                }
            }

            if (image == null) {
                image = cvCreateImage(frame.cvSize(), 8, 3);
                hsv = cvCreateImage(frame.cvSize(), 8, 3);
                hue = cvCreateImage(frame.cvSize(), 8, 1);
                mask = cvCreateImage(frame.cvSize(), 8, 1);
                backproject = cvCreateImage(frame.cvSize(), 8, 1);
                histimg = cvCreateImage(cvSize(320, 200), 8, 3);
                cvZero(histimg);
                hist = cvCreateHist( 1, hdims, CV_HIST_ARRAY, hranges_arr, 1 );

            }
            cvCopy(frame, image);
            if (!paused)
            {
                cvCvtColor(image, hsv, CV_BGR2HSV);

                if (track_object != 0) {

                    int _vmin = vmin, _vmax = vmax;

                    cvInRangeS(hsv, cvScalar(0, smin, Math.min(_vmin, _vmax), 0), cvScalar(180, 256, Math.max(_vmin, _vmax), 0), mask);
                    cvSplit(hsv, hue, null, null, null);

                    hueArray = new IplImageArray(hue);

                    if (track_object < 0) {
                        float max_val = 0.f;

                        cvSetImageROI(hue, selection);
                        cvSetImageROI(mask, selection);
                        cvCalcHist(hueArray, hist, 0, null);


                        if (max_val != 0) { // TODO: entier non null == true en C, à vérifier
                            max_val = (float) 255. / max_val;
                        } else {
                            max_val = 0;
                        }

                        FloatByReference fl_ref = new FloatByReference(max_val);
                        cvConvertScale(hist.bins(), hist.bins(), Float.parseFloat(fl_ref.toString()), 0);
                        cvResetImageROI(hue);
                        cvResetImageROI(mask);
                        track_window = selection;
                        track_object = 1;

                        cvZero(histimg);
                        bin_w = histimg.width() / hsize;
                        for (int i = 0; i < hsize; i++) {
                            int val = Math.round((int) (cvGetReal1D(hist.bins(), i) * histimg.height() / 255.));
                            CvScalar color = hsv2rgb(i * 180.f / hsize);
                            cvRectangle(histimg, cvPoint(i * bin_w, histimg.height()), cvPoint((i + 1) * bin_w, histimg.height() - val), color, -1, 8, 0);
                        }
                    }

                    cvCalcBackProject(hueArray, backproject, hist);
                    cvAnd(backproject, mask, backproject, null);

                    cvCamShift(backproject, track_window, cvTermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1), track_comp, track_box);
                    track_window = track_comp.rect();

//                        if (track_window.width()*track_window.height()<=1)
//                        {
//                            int cols = backproject.width(), rows = backproject.height(), r = (Math.min(cols, rows)+5)/6;
//                            track_window = cvRect(
//                                    Math.max(track_window.x()-r,0), 
//                                    Math.max(track_window.y()-r,0), 
//                                    Math.min(track_window.x()+r,cols), 
//                                    Math.min(track_window.y()+r,rows));
//                        }

                    if (backproject_mode) {
                        cvCvtColor(backproject, image, CV_GRAY2BGR);
                    }
                    if (image.origin() == 0) {
                        track_box = track_box.angle(-track_box.angle());
                        cvEllipseBox(image, track_box, cvScalar(0, 0, 255, 0), 3, CV_AA, 0);
                    }
                }
            } else if (track_object < 0) {
                paused = false;
            }
            if (select_object && selection.width() > 0 && selection.height() > 0) {
                cvSetImageROI(image, selection);
                cvXorS(image, cvScalarAll(255), image, null);
                cvResetImageROI(image);
            } 
            camshiftDemo.showImage(image);
            histogram.showImage(histimg);

        }

    }

@Override
    public void mouseClicked(MouseEvent e) {
//            System.out.println("Mouse Clicked !");

    }

@Override
    public void mousePressed(MouseEvent e) {
        this.onMouse(MOUSE_PRESSED, e.getX(), e.getY());
        System.out.println("Mouse Pressed !");
        System.out.println("\t e.getX(): "+e.getX());
        System.out.println("\t e.getY(): "+e.getY());
    }

@Override
    public void mouseReleased(MouseEvent e) {
        this.onMouse(MOUSE_RELEASED, e.getX(), e.getY());
        System.out.println("Mouse Released !");
        System.out.println("\t e.getX(): "+e.getX());
        System.out.println("\t e.getY(): "+e.getY());
    }

@Override
    public void mouseEntered(MouseEvent e) {
//            System.out.println("Mouse Entered !");

    }

@Override
    public void mouseExited(MouseEvent e) {
//            System.out.println("Mouse Exited !");

    }
}

每次运行应用程序时,在选择要跟踪的对象后,JVM在到达包含cvCalcHist的行时崩溃。

任何人都可以告诉我我的代码有什么问题。我几天以来一直在使用它,我无法弄清楚它的问题:(

非常感谢。

0 个答案:

没有答案
相关问题