1

各ピクセル値がその値と4つの隣接値の平均になるように画像を処理したい。

2 つの異なる関数を作成しました。

Mat meanImage(cv::Mat& inputImage)
{
    Mat output;
    Mat kernel(3,3,CV_32F,0.0);
    kernel.at<float>(0,1) = 0.2;
    kernel.at<float>(1,0) = 0.2;
    kernel.at<float>(1,1) = 0.2;
    kernel.at<float>(1,2) = 0.2;
    kernel.at<float>(2,1) = 0.2;
    filter2D(inputImage,output,-1,kernel);
    return output;
}

と:

Mat meanImage2(Mat& inputImage)
{
    Mat temp;
    Mat output(inputImage.rows,inputImage.cols,inputImage.type());
    copyMakeBorder(inputImage,temp,1,1,1,1,BORDER_REPLICATE);
    CV_Assert(output.isContinuous());
    CV_Assert(temp.isContinuous());
    const int len = output.rows * output.cols * output.channels();
    const int rowLenTemp = temp.cols * temp.channels();
    const int twoRowLenTemp = 2 * rowLenTemp;
    const int rowLen = output.cols * output.channels();
    uchar* outPtr = output.ptr<uchar>(0);
    uchar* tempPtr = temp.ptr<uchar>(0);
    for(int i = 0; i < len; ++i)
    {
        const int a = 6 * (i / rowLen) + 3;
        outPtr[i] = (tempPtr[i+rowLenTemp+a] + tempPtr[i+a] + 
                    tempPtr[i+rowLenTemp+a+3] + tempPtr[i+rowLenTemp+a-3] +   
                    tempPtr[i+twoRowLenTemp+a]) / 5;
    }
    return output;
}

私は結果が同じになると仮定しました。だから私は画像を比較しました:

Mat diff;
compare(meanImg1,meanImg2,diff,CMP_NE);
printf("Difference: %d\n",countNonZero(diff));
imshow("diff",diff);

そして、多くの差をつけてください。この機能の違いは何ですか?

編集:レナから取得したレナ画像の違い

Lena_diff

4

1 に答える 1

2

unsigned charピクセルの合計を行うと、s が追加され、オーバーフローする可能性があることに注意してください。

これらのピクセル値を にキャストして、コードをテストしますint

outPtr[i] = ((int)tempPtr[i+rowLenTemp+a] + (int)tempPtr[i+a] + 
             (int)tempPtr[i+rowLenTemp+a+3] + (int)tempPtr[i+rowLenTemp+a-3] +   
             (int)tempPtr[i+twoRowLenTemp+a]) / 5;

編集:私はむしろこれを次のようにコーディングしたいと思います(画像タイプがucharであり、3つのチャネルがあると仮定します)

for (int r = 0; r < output.rows; r++)
{
  uchar* previousRow = temp.ptr<uchar>(r) + 3; 
  uchar* currentRow = temp.ptr<uchar>(r+1) + 3; 
  uchar* nextRow = temp.ptr<uchar>(r+2) + 3; 

  uchar* outRow = output.ptr<uchar>(r);

  for (int c = 0; c < 3*output.cols; c++)
  {
    int value =              (int)previousRow[c] +  
      (int)currentRow[c-3] + (int)currentRow [c] + (int)currentRow[c+3] + 
                             (int)nextRow    [c];

    outRow[c] = value / 5;
  }
}
于 2013-03-01T15:59:44.277 に答える