-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is there an example of similarity measurement implemented by javacv #1598
Comments
JavaCV comes with a Java mapping of the C++ API of OpenCV, so it should be pretty easy to translate an example written in C++, but if you encounter any issues, please let me know! I will be there to help. |
I wrote code for image similarity measurement with Java. private static double getPSNR(Mat I1, Mat I2) {
Mat s1 = new Mat();
opencv_core.absdiff(I1, I2, s1); // |I1 - I2|
s1.convertTo(s1, opencv_core.CV_32F); // cannot make a square on 8 bits
s1 = s1.mul(s1).asMat(); // |I1 - I2|^2
Scalar s = opencv_core.sumElems(s1); // sum elements per channel
double sse = s.get(0) + s.get(1) + s.get(2); // sum channels
if (sse <= 1e-10) { // for small values return zero
return 0;
} else {
double mse = sse / (double) (I1.channels() * I1.total());
double psnr = 10.0 * Math.log10((255 * 255) / mse);
return psnr;
}
}
private static Scalar getMSSIM(Mat i1, Mat i2) {
double C1 = 6.5025, C2 = 58.5225;
/***************************** INITS **********************************/
int d = opencv_core.CV_32F;
Mat I1 = new Mat();
Mat I2 = new Mat();
i1.convertTo(I1, d); // cannot calculate on one byte large values
i2.convertTo(I2, d);
Mat I2_2 = I2.mul(I2).asMat(); // I2^2
Mat I1_2 = I1.mul(I1).asMat(); // I1^2
Mat I1_I2 = I1.mul(I2).asMat(); // I1 * I2
/*************************** END INITS **********************************/
// PRELIMINARY COMPUTING
Mat mu1 = new Mat();
Mat mu2 = new Mat();
opencv_imgproc.GaussianBlur(I1, mu1, new Size(11, 11), 1.5);
opencv_imgproc.GaussianBlur(I2, mu2, new Size(11, 11), 1.5);
Mat mu1_2 = mu1.mul(mu1).asMat();
Mat mu2_2 = mu2.mul(mu2).asMat();
Mat mu1_mu2 = mu1.mul(mu2).asMat();
Mat sigma1_2 = new Mat();
Mat sigma2_2 = new Mat();
Mat sigma12 = new Mat();
opencv_imgproc.GaussianBlur(I1_2, sigma1_2, new Size(11, 11), 1.5);
sigma1_2 = opencv_core.subtract(sigma1_2, mu1_2).asMat();
opencv_imgproc.GaussianBlur(I2_2, sigma2_2, new Size(11, 11), 1.5);
sigma2_2 = opencv_core.subtract(sigma2_2, mu2_2).asMat();
opencv_imgproc.GaussianBlur(I1_I2, sigma12, new Size(11, 11), 1.5);
sigma12 = opencv_core.subtract(sigma12, mu1_mu2).asMat();
Mat t1, t2, t3;
t1 = opencv_core.add(opencv_core.multiply(2, mu1_mu2), Scalar.all(C1)).asMat();
t2 = opencv_core.add(opencv_core.multiply(2, sigma12), Scalar.all(C2)).asMat();
t3 = t1.mul(t2).asMat(); // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))
t1 = opencv_core.add(opencv_core.add(mu1_2, mu2_2), Scalar.all(C1)).asMat();
t2 = opencv_core.add(opencv_core.add(sigma1_2, sigma2_2), Scalar.all(C2)).asMat();
t1 = t1.mul(t2).asMat(); // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))
Mat ssim_map = new Mat();
opencv_core.divide(t3, t1, ssim_map); // ssim_map = t3./t1;
Scalar mssim = opencv_core.mean(ssim_map); // mssim = average of ssim map
return mssim;
}
public static void main(String[] args) {
Mat img1 = opencv_imgcodecs.imread("img.png");
Mat img2 = img1.clone();
opencv_imgproc.GaussianBlur(img2, img2, new Size(15, 15), 10);
double psnr = getPSNR(img1, img2);
Scalar mssim = getMSSIM(img1, img2);
System.out.println("PSNR: " + psnr);
System.out.printf("SSIM: %f, %f, %f\n", mssim.get(0), mssim.get(1), mssim.get(2));
} example run:
|
Thank you very much for the code! |
@n-kai-cj Thanks! Could you send a pull request to include that as a sample in |
sent pull request #1622 |
asMat out of memory |
@GuaiYiHu Try to call close() on all Mat objects you create that way. |
OpenCV official example are not implemented in Java.
Is there an implementation of javacv?
The text was updated successfully, but these errors were encountered: