|
@@ -0,0 +1,151 @@
|
|
|
+package com.hb.proj.gather.process.diagnose;
|
|
|
+
|
|
|
+import org.opencv.core.Core;
|
|
|
+import org.opencv.core.CvType;
|
|
|
+import org.opencv.core.Mat;
|
|
|
+import org.opencv.core.Scalar;
|
|
|
+import org.opencv.core.Size;
|
|
|
+import org.opencv.imgcodecs.Imgcodecs;
|
|
|
+import org.opencv.imgproc.Imgproc;
|
|
|
+
|
|
|
+public class SSIMExample {
|
|
|
+
|
|
|
+ static {
|
|
|
+ System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static final Scalar C1 = new Scalar(6.5025);
|
|
|
+ private static final Scalar C2 = new Scalar(58.5225);
|
|
|
+
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+
|
|
|
+ String imagePath1="C:\\Users\\cwen\\Desktop\\p2.png";
|
|
|
+ String imagePath2="C:\\Users\\cwen\\Desktop\\p1.png";
|
|
|
+
|
|
|
+ Mat img1 = Imgcodecs.imread(imagePath1, Imgcodecs.IMREAD_GRAYSCALE);
|
|
|
+ Mat img2 = Imgcodecs.imread(imagePath2, Imgcodecs.IMREAD_GRAYSCALE);
|
|
|
+
|
|
|
+ double ssimValue = calculateSSIM2(img1, img2);
|
|
|
+ System.out.println("SSIM: " + ssimValue);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static double calcSimilary(String chartFile1,String chartFile2) {
|
|
|
+ Mat image1 = Imgcodecs.imread(chartFile1,Imgcodecs.IMREAD_GRAYSCALE);
|
|
|
+ Mat image2 = Imgcodecs.imread(chartFile2,Imgcodecs.IMREAD_GRAYSCALE);
|
|
|
+ //System.out.println(image1.size()+":"+image2.size());
|
|
|
+
|
|
|
+ Imgproc.resize(image1, image1, image2.size());
|
|
|
+ return calculateSSIM(image1, image2);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static double calculateSSIM(Mat image1, Mat image2) {
|
|
|
+ Mat validImage1 = new Mat(), validImage2 = new Mat();
|
|
|
+ image1.convertTo(validImage1, CvType.CV_32F); //数据类型转换为 float,防止后续计算出现错误
|
|
|
+ image2.convertTo(validImage2, CvType.CV_32F);
|
|
|
+
|
|
|
+ Mat image1_1 = validImage1.mul(validImage1); //图像乘积
|
|
|
+ Mat image2_2 = validImage2.mul(validImage2);
|
|
|
+ Mat image1_2 = validImage1.mul(validImage2);
|
|
|
+
|
|
|
+ Mat gausBlur1= new Mat(), gausBlur2= new Mat(), gausBlur12= new Mat();
|
|
|
+ Imgproc.GaussianBlur(validImage1, gausBlur1, new Size(11, 11), 1.5); //高斯卷积核计算图像均值
|
|
|
+ Imgproc.GaussianBlur(validImage2, gausBlur2, new Size(11, 11), 1.5);
|
|
|
+ Imgproc.GaussianBlur(image1_2, gausBlur12, new Size(11, 11), 1.5);
|
|
|
+
|
|
|
+ //Mat imageAvgProduct = gausBlur1.mul(gausBlur2); //均值乘积
|
|
|
+ Mat u1Squre = gausBlur1.mul(gausBlur1); //各自均值的平方
|
|
|
+ Mat u2Squre = gausBlur2.mul(gausBlur2);
|
|
|
+
|
|
|
+ Mat imageConvariance= new Mat(), imageVariance1= new Mat(), imageVariance2= new Mat();
|
|
|
+ Mat squreAvg1= new Mat(), squreAvg2= new Mat();
|
|
|
+ Imgproc.GaussianBlur(image1_1, squreAvg1, new Size(11, 11), 1.5); //图像平方的均值
|
|
|
+ Imgproc.GaussianBlur(image2_2, squreAvg2, new Size(11, 11), 1.5);
|
|
|
+
|
|
|
+ //Core.subtract(imageVariance2, squreAvg1, squreAvg2);
|
|
|
+
|
|
|
+ /*
|
|
|
+ imageConvariance = gausBlur12 - gausBlur1.mul(gausBlur2);// 计算协方差
|
|
|
+ imageVariance1 = squreAvg1 - gausBlur1.mul(gausBlur1); //计算方差
|
|
|
+ imageVariance2 = squreAvg2 - gausBlur2.mul(gausBlur2);
|
|
|
+ */
|
|
|
+
|
|
|
+ Core.subtract(gausBlur12, gausBlur1.mul(gausBlur2), imageConvariance);
|
|
|
+ Core.subtract(squreAvg1, gausBlur1.mul(gausBlur1), imageVariance1);
|
|
|
+ Core.subtract(squreAvg2, gausBlur2.mul(gausBlur2), imageVariance2);
|
|
|
+
|
|
|
+ Mat rst=new Mat();
|
|
|
+ Core.multiply(gausBlur1.mul(gausBlur2),new Scalar(2),rst);
|
|
|
+ Core.add(rst, C1, rst);
|
|
|
+
|
|
|
+ Mat rst2=new Mat();
|
|
|
+ Core.multiply(imageConvariance,new Scalar(2),rst2);
|
|
|
+ Core.add(rst2, C2, rst2);
|
|
|
+
|
|
|
+ rst.mul(rst2);
|
|
|
+
|
|
|
+ Mat rst3=new Mat();
|
|
|
+ Core.add(u1Squre, u2Squre, rst3);
|
|
|
+ Core.add(rst3, C1,rst3);
|
|
|
+
|
|
|
+ Mat rst4=new Mat();
|
|
|
+ Core.add(imageVariance1,imageVariance2,rst4);
|
|
|
+ Core.add(rst4,C2,rst4);
|
|
|
+ rst3.mul(rst4);
|
|
|
+
|
|
|
+
|
|
|
+ Mat ssim=new Mat();
|
|
|
+ Core.divide(rst, rst3, ssim);
|
|
|
+
|
|
|
+ return Core.mean(ssim).val[0];
|
|
|
+
|
|
|
+ //member ((2 * gausBlur1 .mul(gausBlur2) + C1).mul(2 * imageConvariance + C2));
|
|
|
+ //auto denominator = ((u1Squre + u2Squre + C1).mul(imageVariance1 + imageVariance2 + C2));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static double calculateSSIM2(Mat image1, Mat image2) {
|
|
|
+ Mat validImage1 = new Mat(), validImage2 = new Mat();
|
|
|
+ image1.convertTo(validImage1, CvType.CV_32F); //数据类型转换为 float,防止后续计算出现错误
|
|
|
+ image2.convertTo(validImage2, CvType.CV_32F);
|
|
|
+
|
|
|
+ Scalar C3=new Scalar(C2.val[0]/2);
|
|
|
+
|
|
|
+ Mat image1_1 = validImage1.mul(validImage1); //图像乘积
|
|
|
+ Mat image2_2 = validImage2.mul(validImage2);
|
|
|
+ Mat image1_2 = validImage1.mul(validImage2);
|
|
|
+
|
|
|
+ Mat gausBlur1= new Mat(), gausBlur2= new Mat(), gausBlur12= new Mat();
|
|
|
+ Imgproc.GaussianBlur(validImage1, gausBlur1, new Size(11, 11), 1.5); //高斯卷积核计算图像均值
|
|
|
+ Imgproc.GaussianBlur(validImage2, gausBlur2, new Size(11, 11), 1.5);
|
|
|
+ Imgproc.GaussianBlur(image1_2, gausBlur12, new Size(11, 11), 1.5);
|
|
|
+
|
|
|
+ //Mat u1Squre = gausBlur1.mul(gausBlur1); //各自均值的平方
|
|
|
+ //Mat u2Squre = gausBlur2.mul(gausBlur2);
|
|
|
+ Mat squreAvg1= new Mat(), squreAvg2= new Mat();
|
|
|
+ Imgproc.GaussianBlur(image1_1, squreAvg1, new Size(11, 11), 1.5); //图像平方的均值
|
|
|
+ Imgproc.GaussianBlur(image2_2, squreAvg2, new Size(11, 11), 1.5);
|
|
|
+
|
|
|
+ Mat imageConvariance= new Mat(),imageVariance1= new Mat(), imageVariance2= new Mat();
|
|
|
+ Core.subtract(gausBlur12, gausBlur1.mul(gausBlur2), imageConvariance);
|
|
|
+ Core.subtract(squreAvg1, gausBlur1.mul(gausBlur1), imageVariance1);
|
|
|
+ Core.subtract(squreAvg2, gausBlur2.mul(gausBlur2), imageVariance2);
|
|
|
+
|
|
|
+ Mat rst=new Mat();
|
|
|
+ Core.add(imageConvariance, C3, rst);
|
|
|
+
|
|
|
+ Mat sqrtVar1=new Mat();
|
|
|
+ Core.sqrt(imageVariance1, sqrtVar1);
|
|
|
+
|
|
|
+ Mat sqrtVar2=new Mat();
|
|
|
+ Core.sqrt(imageVariance2, sqrtVar2);
|
|
|
+
|
|
|
+ Mat rst2=new Mat();
|
|
|
+ sqrtVar1.mul(sqrtVar2);
|
|
|
+ Core.add(sqrtVar1, C3, rst2);
|
|
|
+
|
|
|
+ Mat ssim=new Mat();
|
|
|
+ Core.divide(rst, rst2, ssim);
|
|
|
+
|
|
|
+ return Core.mean(ssim).val[0];
|
|
|
+ }
|
|
|
+}
|