java 调用opencv进行特征点匹配

2025-02-20 16:37

package com.edu.dzsb.opencv;

import com.edu.dzsb.BusinessException;
import org.opencv.core.*;
import org.opencv.features2d.*;
import org.opencv.imgcodecs.Imgcodecs;

import java.util.ArrayList;
import java.util.List;


public class Test
{
public static void main(String[] args)
{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

Mat tmplMat = Imgcodecs.imread("C:\\Users\\jaxer\\Desktop\\ocr\\test\\cannTmpl.jpg", Imgcodecs.IMREAD_GRAYSCALE);
Mat targetMat = Imgcodecs.imread("C:\\Users\\jaxer\\Desktop\\ocr\\test\\cann.jpg", Imgcodecs.IMREAD_GRAYSCALE);
// 初始化 特征检测器
AKAZE akaze = AKAZE.create();
MatOfKeyPoint tmplKeypoints = new MatOfKeyPoint();
MatOfKeyPoint targetKeypoints = new MatOfKeyPoint();
Mat tmplDescriptors = new Mat();
Mat targetDescriptors = new Mat();

akaze.detectAndCompute(tmplMat, new Mat(), tmplKeypoints, tmplDescriptors);
akaze.detectAndCompute(targetMat, new Mat(), targetKeypoints, targetDescriptors);

tmplDescriptors.convertTo(tmplDescriptors,CvType.CV_32F);
targetDescriptors.convertTo(targetDescriptors,CvType.CV_32F);

FlannBasedMatcher flannMatcher = new FlannBasedMatcher();
// 匹配特征点
MatOfDMatch matches = new MatOfDMatch();
flannMatcher.match(tmplDescriptors, targetDescriptors, matches);
Mat out = new Mat();
Features2d.drawMatches(tmplMat, tmplKeypoints, targetMat, targetKeypoints, matches, out);
Imgcodecs.imwrite("C:\\Users\\jaxer\\Desktop\\ocr\\test\\matchResult.jpg",out);
// 转换为 DMatch 数组
DMatch[] matchesArray = matches.toArray();

// 筛选良好匹配点(例如使用 Lowe's ratio test)
double minDist = Double.MAX_VALUE;
System.out.println(minDist);

for (int j = 0; j < tmplDescriptors.rows(); j++) {
double dist = matchesArray[j].distance;
if (dist < minDist){
minDist = dist;
}
}
System.out.println(minDist);

minDist *= 2; // 设置阈值
System.out.println(minDist);

List<DMatch> goodMatches = new ArrayList<>();
for (int j = 0; j < matchesArray.length; j++) {
if (matchesArray[j].distance < minDist) {
goodMatches.add(matchesArray[j]);
}
}

// 获取良好匹配点的坐标
List<Point> templatePoints = new ArrayList<>();
List<Point> targetPoints = new ArrayList<>();
for (DMatch match : goodMatches) {
Point templatePt = tmplKeypoints.toArray()[match.queryIdx].pt;
Point targetPt = targetKeypoints.toArray()[match.trainIdx].pt;
templatePoints.add(templatePt);
targetPoints.add(targetPt);
System.out.println("targetPt"+targetPt.toString());
}


tmplMat.release();
targetMat.release();
tmplDescriptors.release();
targetDescriptors.release();

}
}



代码示例