2

C++ で記述された OpenCV で PSNR の実装を見つけましたが、JavaCV でこれを実装するのに問題があります。

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 を行うには?
  • タイプ Scalar が見つかりません。
  • 合計(s1)を行う方法は?

よろしくお願いいたします。

ジェイソン

4

2 に答える 2

1

この場合、Mat は画像の RGB 値の配列です。この場合のスカラーは、3 つの数値のリストです。

absdiff(I1, I2, s1) は、カラー/グレースケール/rgba チャンネル ect を持つ最初の画像 (I1) からピクセルを取得し、画像 2 (I2) のピクセルから減算して、絶対値を取得すると言っています。差分を取り、最初の要素として割り当てられた Matrix/Array(s1) に保存します。RGB 画像の場合、絶対差 |R1-R2|、|G1-G2|、|B1-B2| が得られます。これらの 3 つの値を保存します。ここで、1 は画像 1 から、2 は画像 2 からのもので、すべてのピクセルに対してこれを行います。

sum(s1) は、2 つの画像の色の違いを格納する s1 で、すべての赤の値を合計し、すべての青の値を合計し、すべての緑の値を合計して、3 つの数値のリストを返します。各色の合計を表しています。

RGB を YMK または使用している他のものに置き換えるだけです。

Matrix や Scalar などの基本型の詳細については、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

「クラス Mat は、行列 (さらに行列と呼ばれる)、画像、オプティカル フロー マップなどとして機能する 2D 数値配列を表します。これは、OpenCV の以前のバージョンの CvMat タイプに非常に似ており、CvMat と同様です。 、マトリックスはマルチチャネルにすることができますが、IplImage と同様に、ROI メカニズムも完全にサポートしています。」

于 2013-06-02T21:00:13.810 に答える
0

私は同じ問題に遭遇し、上記のコードを JavaCV で Java に変換しました。これが私のコードです:

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;
}
于 2013-10-10T08:15:32.443 に答える