1

2枚の写真の違いの数を取得しようとしています。2 つの画像をグレースケールで比較すると pixDiff <> 0 ですが、RGB になると pixDiff は常に 0 です。

openCV の比較とカスタム ループを使用しました。

Mat frame, oldFrame;
cap >> oldFrame;

if(analyseMod == MONOCHROME)
    cvtColor(oldFrame, oldFrame, CV_BGR2GRAY);

nbChannels = oldFrame.channels();

while(1)
{
    pixDiff = 0;
    cap >> frame;

    //Test diff
    Mat diff;
    compare(oldFrame, frame, diff, CMP_NE);
    imshow("video 0", diff);
    imshow("video 1", frame);

    if(analyseMod == MONOCHROME)
    {
        cvtColor(frame, frame, CV_BGR2GRAY);

        for(int i=0; i<frame.rows; i++)
            for(int j=0; j<frame.cols; j++)
                if(frame.at<uchar>(i,j) < oldFrame.at<uchar>(i,j) - similarPixelTolerance || frame.at<uchar>(i,j) > oldFrame.at<uchar>(i,j) + similarPixelTolerance)
                    pixDiff++;
    }
    else if(analyseMod == RGB)
    {
        uint8_t *f = (uint8_t *)frame.data;
        uint8_t *o = (uint8_t *)oldFrame.data;

        for(int i=0; i<frame.rows; i++)
        {
            for(int j=0; j<frame.cols; j++)
            {
                if(f[nbChannels*i*frame.cols + j + RED] < o[nbChannels*i*oldFrame.cols + j + RED])
                    pixDiff++;
            }
        }
    }          

    frame.copyTo(oldFrame);

    cout << pixDiff;
    if(waitKey(30) >= 0) break;
}

助けてくれてありがとう

4

1 に答える 1

3

RGBの場合にデルタを使用しないのはなぜですか。カラーチャネルを個別に検討する場合は、両方のケースの解決策を次に示します。CNモノクロの場合は 1、RGB の場合は 3 に設定します。

const int CN = 3; // 3 for RGB, 1 for monochrome

uint8_t *f = frame.ptr<uint8_t>();
uint8_t *o = oldFrame.ptr<uint8_t>();

for(int i = 0; i < frame.rows; ++i)
{
  for(int j = 0; j < frame.cols; ++j)
  {
    for (int c = 0; c < CN; ++c)
    {
      if (abs(*f - *o) > similarPixelTolerance) ++pxDiff;
      ++f, ++o;
    }
  }
}

この方法でピクセルにアクセスする方がat、各ピクセルを呼び出すよりもはるかに効率的です。考えられる唯一の問題は、画像にパディングがある場合ですが、デフォルトで OpenCV は連続割り当てを使用しています。

于 2012-08-19T17:02:45.820 に答える