import java.util.ArrayList;
import java.util.List;
import org.opencv.calib3d.Calib3d;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.DMatch;
导入 org.opencv.core.KeyPoint;
导入 org.opencv.core.Mat;
导入 org.opencv.core.MatOfByte;
导入 org.opencv.core.MatOfDMatch;
导入 org.opencv.core.MatOfKeyPoint;
导入 org.opencv.core.MatOfPoint2f;
导入 org.opencv.core.Point;
导入 org.opencv.core.Scalar;
导入 org.opencv.features2d.DescriptorMatcher;
导入 org.opencv.features2d.Features2d;
导入 org.opencv.highgui.HighGui;
导入 org.opencv.imgcodecs.Imgcodecs;
导入 org.opencv.imgproc.Imgproc;
导入 org.opencv.xfeatures2d.SURF;
类 SURFFLANNMatchingHomography {
公有 无效 run(String[] args) {
String filenameObject = args.length > 1 ? args[0] : "../data/box.png";
String filenameScene = args.length > 1 ? args[1] : "../data/box_in_scene.png";
Mat imgObject = Imgcodecs.imread(filenameObject, Imgcodecs.IMREAD_GRAYSCALE);
Mat imgScene = Imgcodecs.imread(filenameScene, Imgcodecs.IMREAD_GRAYSCALE);
如果 (imgObject.empty() || imgScene.empty()) {
System.err.println("无法读取图片!");
System.exit(0);
}
双精度 hessianThreshold = 400;
整型 nOctaves = 4, nOctaveLayers = 3;
布尔 extended = 错误, upright = 错误;
SURF detector = SURF.create(hessianThreshold, nOctaves, nOctaveLayers, extended, upright);
MatOfKeyPoint keypointsObject = 新 MatOfKeyPoint(), keypointsScene = 新 MatOfKeyPoint();
Mat descriptorsObject = 新 Mat(), descriptorsScene = 新 Mat();
detector.detectAndCompute(imgObject, 新 Mat(), keypointsObject, descriptorsObject);
detector.detectAndCompute(imgScene, 新 Mat(), keypointsScene, descriptorsScene);
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);
List<MatOfDMatch> knnMatches = 新 ArrayList<>();
matcher.knnMatch(descriptorsObject, descriptorsScene, knnMatches, 2);
浮点 ratioThresh = 0.75f;
List<DMatch> listOfGoodMatches = 新 ArrayList<>();
对于 (整型 i = 0; i < knnMatches.size(); i++) {
如果 (knnMatches.get(i).rows() > 1) {
DMatch[] matches = knnMatches.get(i).toArray();
如果 (matches[0].distance < ratioThresh * matches[1].distance) {
listOfGoodMatches.add(matches[0]);
}
}
}
MatOfDMatch goodMatches = 新 MatOfDMatch();
goodMatches.fromList(listOfGoodMatches);
Mat imgMatches = 新 Mat();
Features2d.drawMatches(imgObject, keypointsObject, imgScene, keypointsScene, goodMatches, imgMatches,
标量.
全部(-1),
标量.
全部(-1),
新 MatOfByte(), Features2d.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS);
列表<点> obj = 新 ArrayList<>();
列表<点> scene = 新 ArrayList<>();
列表<关键点> listOfKeypointsObject = keypointsObject.toList();
列表<关键点> listOfKeypointsScene = keypointsScene.toList();
对于 (整数 i = 0; i < listOfGoodMatches.size(); i++) {
obj.add(listOfKeypointsObject.get(listOfGoodMatches.get(i).queryIdx).pt);
scene.add(listOfKeypointsScene.get(listOfGoodMatches.get(i).trainIdx).pt);
}
MatOfPoint2f objMat = 新 MatOfPoint2f(), sceneMat = 新 MatOfPoint2f();
objMat.fromList(obj);
sceneMat.fromList(scene);
双精度 ransacReprojThreshold = 3.0;
Mat H = Calib3d.findHomography( objMat, sceneMat, Calib3d.RANSAC, ransacReprojThreshold );
Mat objCorners = 新 Mat(4, 1, CvType.CV_32FC2), sceneCorners = 新 Mat();
浮点[] objCornersData = 新 浮点[(int) (objCorners.total() * objCorners.channels())];
objCorners.get(0, 0, objCornersData);
objCornersData[0] = 0;
objCornersData[1] = 0;
objCornersData[2] = imgObject.cols();
objCornersData[3] = 0;
objCornersData[4] = imgObject.cols();
objCornersData[5] = imgObject.rows();
objCornersData[6] = 0;
objCornersData[7] = imgObject.rows();
objCorners.put(0, 0, objCornersData);
Core.perspectiveTransform(objCorners, sceneCorners, H);
浮点[] sceneCornersData = 新 浮点[(int) (sceneCorners.total() * sceneCorners.channels())];
sceneCorners.get(0, 0, sceneCornersData);
Imgproc.line(imgMatches,
新 点(sceneCornersData[0] + imgObject.cols(), sceneCornersData[1]),
新 点(sceneCornersData[2] + imgObject.cols(), sceneCornersData[3]),
新 标量(0, 255, 0), 4);
Imgproc.line(imgMatches,
新 点(sceneCornersData[2] + imgObject.cols(), sceneCornersData[3]),
新 点(sceneCornersData[4] + imgObject.cols(), sceneCornersData[5]),
新 标量(0, 255, 0), 4);
Imgproc.line(imgMatches,
新 点(sceneCornersData[4] + imgObject.cols(), sceneCornersData[5]),
new Point(sceneCornersData[6] + imgObject.cols(), sceneCornersData[7]),
new Scalar(0, 255, 0), 4);
Imgproc.line(imgMatches,
new Point(sceneCornersData[6] + imgObject.cols(), sceneCornersData[7]),
new Point(sceneCornersData[0] + imgObject.cols(), sceneCornersData[1]),
new Scalar(0, 255, 0), 4);
HighGui.imshow("Good Matches & Object detection", imgMatches);
HighGui.waitKey(0);
System.exit(0);
}
}
public class SURFFLANNMatchingHomographyDemo {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
new SURFFLANNMatchingHomography().run(args);
}
}
static Scalar_< _Tp > all(_Tp v0)
返回一个标量,其中所有元素均设置为 v0
Point2i Point
定义 types.hpp:209
Scalar_< double > Scalar
定义 types.hpp:702