0

我正在尝试实现使用 JavaCv Surf 的示例。我下载了示例代码、.jar 文件并安装了官方网页要求的所有内容 (http://code.google.com/p/javacv/)。但是似乎缺少一个函数: cvExtractSURF() 无论我做什么,我都无法让 Netbeans 或 Eclipse 编译该示例。也许我做错了什么,或者该函数有一个新名称或其他一些参数。这是我错误代码的快照

import com.googlecode.javacv.cpp.opencv_core;
import com.googlecode.javacv.cpp.opencv_core.CvMemStorage;
import com.googlecode.javacv.cpp.opencv_core.CvSeq;
import com.googlecode.javacv.cpp.opencv_core.CvSeqReader;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import com.googlecode.javacv.cpp.opencv_features2d.*;
import com.googlecode.javacv.cpp.opencv_imgproc;
import com.googlecode.javacv.cpp.opencv_imgproc.CvChainPtReader;
import com.googlecode.javacv.cpp.opencv_legacy.CvSURFParams;
import com.googlecode.javacv.cpp.opencv_legacy.CvSURFPoint;
import java.awt.Point;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.MappedByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;


public class SurftDetection {

    public static Hashtable<Point2D,Point2D> detectSurfPts(BufferedImage object, BufferedImage image) {
        IplImage firstFrame = IplImage.createFrom(object);
        IplImage secondFrame = IplImage.createFrom(image);


        CvSeq objectKeypoints = new CvSeq(null);
        CvSeq objectDescriptors = new CvSeq(null);
        CvSeq imageKeypoints = new CvSeq(null);
        CvSeq imageDescriptors = new CvSeq(null);

        CvSURFParams params = new CvSURFParams();
        params.extended(1).hessianThreshold(500).nOctaves(3).nOctaveLayers(4);

        IplImage firstFramegray = opencv_core.cvCreateImage(opencv_core.cvSize(firstFrame.width(),firstFrame.height()), opencv_core.IPL_DEPTH_8U, 1);
        opencv_imgproc.cvCvtColor(firstFrame, firstFramegray,opencv_imgproc.CV_BGR2GRAY);

        IplImage secondFramecolor = opencv_core.cvCreateImage(opencv_core.cvGetSize(secondFrame), opencv_core.IPL_DEPTH_8U, 1);
        opencv_imgproc.cvCvtColor(secondFrame, secondFramecolor,opencv_imgproc.CV_BGR2GRAY);
        // convert images to grayscale

        // compute surf
        CvMemStorage storage1 = CvMemStorage.create();
        opencv_core.cvClearMemStorage(storage1);
        cvExtractSURF(firstFramegray, null, objectKeypoints, objectDescriptors, storage1, params, 0);

        CvMemStorage storage2 = CvMemStorage.create();
        opencv_core.cvClearMemStorage(storage2);
        cvExtractSURF(secondFramecolor, null, imageKeypoints, imageDescriptors, storage2, params, 0);

        return findPairs(objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors);
    }

    private static double compareSURFDescriptors(FloatBuffer d1, FloatBuffer d2, double best) {
        double totalCost = 0;
        assert (d1.capacity() == d2.capacity() && d1.capacity() % 4 == 0);
        for (int i = 0; i < d1.capacity(); i += 4 ) {
            double t0 = d1.get(i  ) - d2.get(i  );
            double t1 = d1.get(i+1) - d2.get(i+1);
            double t2 = d1.get(i+2) - d2.get(i+2);
            double t3 = d1.get(i+3) - d2.get(i+3);
            totalCost += t0*t0 + t1*t1 + t2*t2 + t3*t3;
            if (totalCost > best)
                break;
        }
        return totalCost;
    }

    private static int naiveNearestNeighbor(FloatBuffer vec, int laplacian,
        CvSURFPoint[] modelKeypoints, FloatBuffer[] modelDescriptors) {
        int neighbor = -1;
        double d, dist1 = 1e6, dist2 = 1e6;
        for (int i = 0; i < modelDescriptors.length; i++) {
            CvSURFPoint kp = modelKeypoints[i];
            FloatBuffer mvec = modelDescriptors[i];
            if (laplacian != kp.laplacian()) {
                continue;
            }
            d = compareSURFDescriptors(vec, mvec, dist2);
            if (d < dist1) {
                dist2 = dist1;
                dist1 = d;
                neighbor = i;
            } else if (d < dist2) {
                dist2 = d;
            }
        }
        if (dist1 < 0.6 * dist2) {
            return neighbor;
        }
        return -1;
    }

    private static ArrayList<Integer> findPairs(CvSURFPoint[] objectKeypoints, FloatBuffer[] objectDescriptors,
        CvSURFPoint[] imageKeypoints, FloatBuffer[] imageDescriptors) {
        ArrayList<Integer> ptpairs = new ArrayList<Integer>(2 * objectDescriptors.length);
        for (int i = 0; i < objectDescriptors.length; i++) {
            CvSURFPoint kp = objectKeypoints[i];
            FloatBuffer descriptor = objectDescriptors[i];
            int nearestNeighbor = naiveNearestNeighbor(descriptor, kp.laplacian(), imageKeypoints, imageDescriptors);
            if (nearestNeighbor >= 0) {
                ptpairs.add(i);
                ptpairs.add(nearestNeighbor);
            }
        }
        return ptpairs;
    }

    private static Hashtable<Point2D,Point2D> findPairs(CvSeq objectKeypoints, CvSeq objectDescriptors, CvSeq imageKeypoints, CvSeq imageDescriptors) {

        //CvSeqReader reader = new CvSeqReader(), kreader = new CvSeqReader();

        // copy object info
        int total = objectDescriptors.total();
        int elem_size = objectDescriptors.elem_size();
//        opencv_core.cvStartReadSeq(objectKeypoints, kreader, total);
//        opencv_core.cvStartReadSeq(objectDescriptors, reader, elem_size);

        CvSURFPoint[] objectKeypointsArr = new CvSURFPoint[total];
        FloatBuffer[] objectDescriptorsArr = new FloatBuffer[total];

        for (int i = 0; i < total; i++) {
//            objectKeypointsArr[i] = new opencv_features2d.CvSURFPoint(kreader.ptr());
//            objectDescriptorsArr[i] = reader.ptr().capacity(elem_size).asByteBuffer().asFloatBuffer();
            objectKeypointsArr[i] = new CvSURFPoint(opencv_core.cvGetSeqElem(objectKeypoints, i));
            objectDescriptorsArr[i] = opencv_core.cvGetSeqElem(objectDescriptors,i).capacity(elem_size).asByteBuffer().asFloatBuffer();
//            opencv_core.CV_NEXT_SEQ_ELEM(kreader.seq().elem_size(), kreader);
//            opencv_core.CV_NEXT_SEQ_ELEM(reader.seq().elem_size(), reader);
        }

        total = imageDescriptors.total();
        elem_size = imageDescriptors.elem_size();

        CvSURFPoint[] imageKeypointsArr = new CvSURFPoint[total];
        FloatBuffer[] imageDescriptorsArr = new FloatBuffer[total];

//        opencv_core.cvStartReadSeq(imageKeypoints, kreader, 0);
//        opencv_core.cvStartReadSeq(imageDescriptors, reader, 0);

        for (int i = 0; i < total; i++) {
            imageKeypointsArr[i] = new CvSURFPoint(opencv_core.cvGetSeqElem(imageKeypoints, i));
            imageDescriptorsArr[i] = opencv_core.cvGetSeqElem(imageDescriptors,i).capacity(elem_size).asByteBuffer().asFloatBuffer();
//            opencv_core.CV_NEXT_SEQ_ELEM(kreader.seq().elem_size(), kreader);
//            opencv_core.CV_NEXT_SEQ_ELEM(reader.seq().elem_size(), reader);
        }

        ArrayList<Integer> pairs = findPairs(objectKeypointsArr,objectDescriptorsArr,imageKeypointsArr,imageDescriptorsArr);

        Hashtable<Point2D,Point2D> map = new Hashtable<Point2D, Point2D>(pairs.size());
        for(int i=0;i<pairs.size();i+=2){
            map.put(new Point2D.Float(objectKeypointsArr[pairs.get(i)].pt().x(), objectKeypointsArr[pairs.get(i)].pt().y()),
                    new Point2D.Float(imageKeypointsArr[pairs.get(i+1)].pt().x(), imageKeypointsArr[pairs.get(i+1)].pt().y()));
        }
        return map;
    }

    public static BufferedImage resizeImage(BufferedImage im, int new_Width, int new_height){
        IplImage cv_im = IplImage.createFrom(im);
        IplImage cv_res = IplImage.create(new_Width, new_height, cv_im.depth(), cv_im.nChannels());
        opencv_imgproc.cvResize(cv_im, cv_res);
        return cv_res.getBufferedImage();
    }

    public static IplImage resizeImage(IplImage cv_im, int new_Width, int new_height){
        IplImage cv_res = IplImage.create(new_Width, new_height, cv_im.depth(), cv_im.nChannels());
        opencv_imgproc.cvResize(cv_im, cv_res);
        return cv_res;
    }

}
4

1 回答 1

1

尝试导入

import static com.googlecode.javacv.cpp.opencv_legacy.cvExtractSURF;

或更一般的

import static com.googlecode.javacv.cpp.opencv_legacy.*;
于 2014-04-07T16:17:26.637 回答