gpt4 book ai didi

java - Opencv - Features2D + Homography 不正确的结果

转载 作者:搜寻专家 更新时间:2023-11-01 03:35:19 26 4
gpt4 key购买 nike

我在将检测到的对象的轮廓放在正确位置时遇到了一些问题,就好像坐标在错误的位置一样。我将 hessian 设置为 2000,并且过滤了小于最小距离 3 倍的匹配项。任何帮助,将不胜感激。

运行匹配和单应性的结果:

下面的代码示例:

public static void findMatches()
{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

//Load Image 1
Mat img_object = Highgui.imread("./resources/Database/box.png");
//Load Image 2
Mat img_scene = Highgui.imread("./resources/Database/box_in_scene.png");

//Check if either image is null if so exit application
if (img_object == null || img_scene == null)
{
System.exit(0);
}

//Convert Image 1 to greyscale
Mat grayImageobject = new Mat(img_object.rows(), img_object.cols(), img_object.type());
Imgproc.cvtColor(img_object, grayImageobject, Imgproc.COLOR_BGRA2GRAY);
Core.normalize(grayImageobject, grayImageobject, 0, 255, Core.NORM_MINMAX);

//Convert image 2 to greyscale
Mat grayImageScene = new Mat(img_scene.rows(), img_scene.cols(), img_scene.type());
Imgproc.cvtColor(img_scene, grayImageScene, Imgproc.COLOR_BGRA2GRAY);
Core.normalize(grayImageScene, grayImageScene, 0, 255, Core.NORM_MINMAX);

//Create a SURF feature detector
FeatureDetector detector = FeatureDetector.create(4); //4 = SURF

//Cannot input hessian value as normal so we have to write the desired value into a
//file and then read value from file into detector.read
try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("hessian.txt"), "utf-8"))) {
writer.write("%YAML:1.0\nhessianThreshold: 2000.\noctaves:3\noctaveLayers: 4\nupright: 0\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

detector.read("hessian.txt");

//Mat of keypoints for object and scene
MatOfKeyPoint keypoints_object = new MatOfKeyPoint();
MatOfKeyPoint keypoints_scene = new MatOfKeyPoint();

//Detect keypoints in scene and object storing them in mat of keypoints
detector.detect(img_object, keypoints_object);
detector.detect(img_scene, keypoints_scene);

DescriptorExtractor extractor = DescriptorExtractor.create(2); //2 = SURF;

Mat descriptor_object = new Mat();
Mat descriptor_scene = new Mat() ;

extractor.compute(img_object, keypoints_object, descriptor_object);
extractor.compute(img_scene, keypoints_scene, descriptor_scene);

DescriptorMatcher matcher = DescriptorMatcher.create(1); // 1 = FLANNBASED
MatOfDMatch matches = new MatOfDMatch();

matcher.match(descriptor_object, descriptor_scene, matches);
List<DMatch> matchesList = matches.toList();

Double max_dist = 0.0;
Double min_dist = 100.0;

for(int i = 0; i < descriptor_object.rows(); i++){
Double dist = (double) matchesList.get(i).distance;
if(dist < min_dist) min_dist = dist;
if(dist > max_dist) max_dist = dist;
}

System.out.println("-- Max dist : " + max_dist);
System.out.println("-- Min dist : " + min_dist);

LinkedList<DMatch> good_matches = new LinkedList<DMatch>();
MatOfDMatch gm = new MatOfDMatch();

for(int i = 0; i < descriptor_object.rows(); i++){
if(matchesList.get(i).distance < 3*min_dist){
good_matches.addLast(matchesList.get(i));
}
}

gm.fromList(good_matches);

Mat img_matches = new Mat();
Features2d.drawMatches(img_object,keypoints_object,img_scene,keypoints_scene, gm, img_matches, new Scalar(255,0,0), new Scalar(0,0,255), new MatOfByte(), 2);

if(good_matches.size() >= 10){

LinkedList<Point> objList = new LinkedList<Point>();
LinkedList<Point> sceneList = new LinkedList<Point>();

List<KeyPoint> keypoints_objectList = keypoints_object.toList();
List<KeyPoint> keypoints_sceneList = keypoints_scene.toList();

for(int i = 0; i<good_matches.size(); i++){
objList.addLast(keypoints_objectList.get(good_matches.get(i).queryIdx).pt);
sceneList.addLast(keypoints_sceneList.get(good_matches.get(i).trainIdx).pt);
}

MatOfPoint2f obj = new MatOfPoint2f();
obj.fromList(objList);

MatOfPoint2f scene = new MatOfPoint2f();
scene.fromList(sceneList);

Mat homography = Calib3d.findHomography(obj, scene);

Mat obj_corners = new Mat(4,1,CvType.CV_32FC2);
Mat scene_corners = new Mat(4,1,CvType.CV_32FC2);

obj_corners.put(0, 0, new double[] {0,0});
obj_corners.put(1, 0, new double[] {img_object.cols(),0});
obj_corners.put(2, 0, new double[] {img_object.cols(),img_object.rows()});
obj_corners.put(3, 0, new double[] {0,img_object.rows()});

//Compute the most probable perspective transformation
//out of several pairs of corresponding points.
//Imgproc.getPerspectiveTransform(obj_corners, scene_corners);
Core.perspectiveTransform(obj_corners,scene_corners, homography);

Core.line(img_matches, new Point(scene_corners.get(0,0)), new Point(scene_corners.get(1,0)), new Scalar(0, 255, 0),4);
Core.line(img_matches, new Point(scene_corners.get(1,0)), new Point(scene_corners.get(2,0)), new Scalar(0, 255, 0),4);
Core.line(img_matches, new Point(scene_corners.get(2,0)), new Point(scene_corners.get(3,0)), new Scalar(0, 255, 0),4);
Core.line(img_matches, new Point(scene_corners.get(3,0)), new Point(scene_corners.get(0,0)), new Scalar(0, 255, 0),4);

Highgui.imwrite("./resources/ImageMatching" + ".jpg", img_matches);
createWindow("Image Matching", "resources/ImageMatching.jpg");
}
else
{
System.out.println("Not enough Matches");
System.exit(0);
}
}

最佳答案

坐标 在正确的位置,您只是在错误的图像上绘图。

您的坐标是相对于第二张图片 img_scene 的。因此,如果您只在该图像上画线,它们就是正确的。

如果你想在合成图像上绘制线条,其中 img_scene 向右平移第一个图像 img_object 的宽度,你只需添加img_object.cols() 到点 x 坐标。

例如:

Core.line(img_matches, 
new Point(scene_corners.get(0,0)[0] + img_object.cols(), scene_corners.get(0,0)[1]),
new Point(scene_corners.get(1,0)[0] + img_object.cols(), scene_corners.get(1,0)[1]),
new Scalar(0, 255, 0),4);

对于第一行,接下来的三行相同。

关于java - Opencv - Features2D + Homography 不正确的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33791591/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com