Java使用OpenCV计算两张图片相似度

业务:找出两个表的重复的图片。

图片在表里存的是二进制值,存在大量由于一些特殊情况例如扫描有差异,导致图片存的二进制值不同,但图片其实是一样来的。

所以找出两个表重复相同的图片,不可能只是单纯的比较二进制值相等。

方法:针对这种情况,使用OpenCV直方图算法可以比较两张图片的相似度,测试发现完全相同的图片相似度等于1(表里存的二进制值不相等)

实操:Java引入使用opencv步骤详解

1.引入opencv依赖

<!-- https://mvnrepository.com/artifact/org.openimaj/core -->
<dependency>
	<groupId>org.openpnp</groupId>
	<artifactId>opencv</artifactId>
	<version>4.5.5-1</version>
</dependency>

2.代码Demo

opencv提供了均方差算法(MSE)、结构相似性指数算法(SSIM)、峰值信噪比算法(PSNR)、直方图算法(SSIM-WH),其中使用直方图算法来比较图片相似效果最好。

    public static void main(String[] args) {
        // 加载OpenCV库
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

        // 读取两张图像。准备比对的图片
        Mat image1 = Imgcodecs.imread("D:\\work\\testdata\\psc_1716260008343.jpg");
        Mat image2 = Imgcodecs.imread("D:\\work\\testdata\\psc_1716260008345.jpg");

        // 将图片处理成一样大
        Imgproc.resize(image1, image1, image2.size());
        Imgproc.resize(image2, image2, image1.size());

        // 计算均方差(MSE)
        double mse = calculateMSE(image1, image2);
        System.out.println("均方差(MSE): " + mse);

        // 计算结构相似性指数(SSIM)
        double ssim = calculateSSIM(image1, image2);
        System.out.println("结构相似性指数(SSIM): " + ssim);

        // 计算峰值信噪比(PSNR)
        double psnr = calculatePSNR(image1, image2);
        System.out.println("峰值信噪比(PSNR): " + psnr);

        // 计算直方图
        final double similarity = calculateHistogram(image1, image2);
        System.out.println("图片相似度(直方图): " + 
使用JavaOpenCV计算两张图片相似度,可以采用以下步骤: 1. 加载图片使用OpenCVJava接口,加载两张待比较的图片,可以使用Imgcodecs.imread方法读取图片。 2. 提取特征:使用OpenCV的FeatureDetector和DescriptorExtractor等类,对图片进行特征提取和描述。 3. 计算相似度使用OpenCV的DescriptorMatcher类,将提取的特征进行匹配,并计算相似度。 下面是一个简单的Java代码示例: ``` import org.opencv.core.*; import org.opencv.features2d.*; import org.opencv.imgcodecs.Imgcodecs; public class ImageMatcher { public static void main(String[] args) { // 加载图片 Mat img1 = Imgcodecs.imread("image1.jpg"); Mat img2 = Imgcodecs.imread("image2.jpg"); // 提取ORB特征 ORB orb = ORB.create(); MatOfKeyPoint keypoints1 = new MatOfKeyPoint(); MatOfKeyPoint keypoints2 = new MatOfKeyPoint(); Mat descriptors1 = new Mat(); Mat descriptors2 = new Mat(); orb.detectAndCompute(img1, new Mat(), keypoints1, descriptors1); orb.detectAndCompute(img2, new Mat(), keypoints2, descriptors2); // 计算相似度 DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING); MatOfDMatch matches = new MatOfDMatch(); matcher.match(descriptors1, descriptors2, matches); // 输出相似度 double maxDist = 0; double minDist = 100; DMatch[] matchArray = matches.toArray(); for (int i = 0; i < matchArray.length; i++) { double dist = matchArray[i].distance; if (dist < minDist) minDist = dist; if (dist > maxDist) maxDist = dist; } double similarity = (1 - minDist / maxDist) * 100; System.out.println("相似度:" + similarity + "%"); } } ``` 在这个例子中,我们使用OpenCV的ORB算法进行特征提取,使用了Hamming距离进行特征匹配,计算出了两张图片相似度。请注意,在实际应用中可能需要根据具体情况选择不同的算法和参数,以获得更准确的结果。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

偏执网友

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值