2010-12-28 8 views
4

何らかの理由により、コードがうまく機能しません。私は非常によく似ていますが、同じではない2つの640 * 480の画像を持っています(少なくとも数百/千ピクセルは違うはずです)。OpenCVは2つの画像を比較し、異なるピクセルを取得します

これは私がそれらを比較し、異なる画素をカウントしています方法です:今

unsigned char* row; 
unsigned char* row2; 
int count = 0; 

// this happens in a loop 
// fIplImageHeader is current image 
// lastFIplImageHeader is image from previous iteration 
if (NULL != lastFIplImageHeader->imageData) { 
for(int y = 0; y < fIplImageHeader->height; y++) 
{ 
    row = &CV_IMAGE_ELEM(fIplImageHeader, unsigned char, y, 0); 
    row2 = &CV_IMAGE_ELEM(lastFIplImageHeader, unsigned char, y, 0); 
    for(int x = 0; x < fIplImageHeader->width*fIplImageHeader->nChannels; x += fIplImageHeader->nChannels) 
    { 
     if(row[x] != row2[x] || row[x+1] != row2[x+1] || row[x+2] != row2[x+2]) 
      count++; 
     } 
    } 
} 
} 

最後に、私は大丈夫と思われる数3626を取得します。

しかし、私はMSペイントで画像の1つを開こうとしましたが、濃い赤色の線が全体に広がっていました。私は再び同じ番号を持っています:3626.

明らかに私はここで何か間違っています。

これらの画像をループ内で比較しています。

この行はループの前にある:

IplImage* fIplImageHeader = cvLoadImage(filePath.c_str()); 

// here I compare the pixels (the first code snippet) 

lastFIplImageHeader->imageData = fIplImageHeader->imageData; 

のでlastFIplImageHeaderは前回の反復からの画像を記憶しているとfIplImageHeaderが保存されています

IplImage* lastFIplImageHeader = cvCreateImageHeader(cvSize(640, 480), 8, 3); 

は、ループ内で私はこのような画像を読み込みます現在の画像。

答えて

5

私は、あなたが別のピクセルを数えていないように見えます。
最初のイメージの1ピクセルのカラーチャネルが、他のイメージの対応するピクセルのチャネルと一致する頻度をカウントしています。

あなたはおそらくの線に沿って何かをする意味:これは(存在する場合)ただし、アルファチャンネルを考慮していますし、あなたがの範囲外読むかもしれないとして、グレースケール画像に失敗します

... 
//in the inner for loop 
if(row[x] != row2[x] || row[x+1] != row2[x+1] || row[x+2] != row2[x+2]) 
    count++; 
... 

データ配列。

編集: 古いイメージを解放しない限り、正常であるはずです。あるいは、

//make sure size and channels are correct. 
//If unsure, load the image first and then create with the parameters taken from the loaded image. 
cvCreateImage(cvSize(640, 480), 8, 3); 

//use cvCopy to copy the contents and proceed as normal 
cvCopy(fIplImageHeader , lastFIplImageHeader); 

コピーの代わり、あなただけの限り、あなたはそれを放出しないよう、古い画像へのポインタを保持し、それを使用できます。しかし、のような何かをする方がよいかもしれません。

lastFIplImageHeader = fIplImageHeader; 
fIplImageHeader = cvLoadImage(filePath.c_str()); 

EDIT2:違いは、あなたが望むすべてである場合は、cvCountNonZero

+0

あなたはおそらく正しいでしょう。しかし、私は常に同じ数字を得る:3626。lastFIplImageHeaderに以前のイメージを保存する方法にはいくつか問題があると思います。 –

+0

私は私の答えを編集しました。 – Darcara

+0

私は夕方に試して、それがどのように行ったかを知らせます。私は今(私は仕事中です)多くの時間がありません。 –

8
int count_diff_pixels(cv::Mat in1, cv::Mat in2) { 
    cv::Mat diff; 
    cv::compare(in1, in2, diff, cv::CMP_NE); 
    return cv::countNonZero(diff); 
} 

が続く、(グレースケールとしてロードされた両方の画像付き)cvSubを見ている可能性がいくつかの調整が必要になる場合があります、それはあなたがそれをやる方法です。また、実際にC++を使用している場合は、cv *を使いこなすべきではありません。新しいC++インターフェイスを使用し、イメージの解放について心配しないでください。前の画像を覚えているだけで簡単になります

cv::Mat prev; 
while (...) { 
    cv::Mat current = cv::imread(fn); // or whereever your image comes from 
    // ... do something ... 
    prev = current; 
} // automatic memory management! 
関連する問題