我正在尝试实现使用 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;
}
}