2013-06-02 38 views
2

我發現C++編寫的PSNR的OpenCV的實現,但我有麻煩JavaCV來實現這一點。如何在JavaCV中實現PSNR?

http://docs.opencv.org/doc/tutorials/highgui/video-input-psnr-ssim/video-input-psnr-ssim.html#image-similarity-psnr-and-ssim

double getPSNR(const Mat& I1, const Mat& I2) 
{ 
Mat s1; 
absdiff(I1, I2, s1);  // |I1 - I2| 
s1.convertTo(s1, CV_32F); // cannot make a square on 8 bits 
s1 = s1.mul(s1);   // |I1 - I2|^2 

Scalar s = sum(s1);   // sum elements per channel 

double sse = s.val[0] + s.val[1] + s.val[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*log10((255*255)/mse); 
    return psnr; 
} 
} 

例如:

  • 什麼是墊類型?是否與JavaCV中的MatVector相同?
  • 如何爲MatVector做absdiff?
  • 我找不到類型標量。
  • 如何做sum(s1)?

感謝和問候,

傑森

回答

1

在這種情況下墊RGB值從圖像陣列。 標量在這種情況下是3個數字的列表。

什麼absdiff(I1,I2,s1)是說你從你的第一個圖像(I1)有一個像素,它有彩色/灰度/ RGB通道等並從圖像2(I2)中的像素中減去它,然後將其存儲在您分配的Matrix/Array(s1)中作爲第一個元素。如果你有一個RGB圖像,你會得到絕對的差異| R1-R2 |,| G1-G2 |,| B1-B2 |並存儲這3個值,其中1來自圖像1,而2來自圖像2,對於所有像素都這樣做。

什麼總和(s1)說,在s1中存儲顏色差異從兩個圖像,總結所有的紅色值,總結所有的藍色值,並總結所有的綠色值,並返回一個3個數字的列表,表示每種顏色的總數。

只是YMK或其他任何你可能會使用替代RGB。關於基本類型,包括矩陣和標量

的更多信息可在這裏OpenCV的文檔中找到:http://opencv.willowgarage.com/documentation/cpp/basic_structures.html和一些代碼可以將該文件和目錄附近找到:https://github.com/Itseez/opencv/blob/master/modules/core/include/opencv2/core/types_c.h

「的類墊表示2D數值陣列可以充當基質(並且進一步它被稱爲基質),圖像,光流圖等,這是非常相似的從早期版本的OpenCV與CvMat類型,和同樣地與CvMat,所述基質可以是多通道的,但它也完全支持ROI機制,就像IplImage一樣。「

+1

thanks gmlime!我會試一試。 –

0

我遇到了同樣的問題,翻譯上面的代碼轉換成Java與JavaCV。這裏是我的代碼:

private static double getPSNR(CvMat I1, CvMat I2) {  
    CvMat s1 = CvMat.create(I1.rows(), I1.cols(), I1.depth(), I1.nChannels()); //create matrix with same size as I1 
    cvAbsDiff(I1, I2, s1); // |I1 - I2| 

    CvMat s1_squared = cvCreateMat(s1.rows(), s1.cols(), CV_32FC3); //convert mat to 32bit and 3 channels 
    cvMul(s1, s1, s1_squared, 1); // |I1 - I2| ^2 

    CvScalar scalar = cvSum(s1_squared); // sum elements per channel 
    double sse = scalar.getVal(0) + scalar.getVal(1) + scalar.getVal(2); // sum channels 

    double mse = sse/(double) (s1.channels() * s1.total()); 
    double psnr = 10.0 * Math.log10((255*255)/mse); 

    return psnr; 
}