OpenGL de プログラミング - OpenCV::相違度(SSD)
現在地 >> メニュー >> サンプルコード::OpenCV >> OpenCV::相違度(SSD)

問題


同じサイズ、同じチャネルの画像を用意して、
SSD(Sum of Squared Difference)で画像の相違度を計算せよ

画像1
画像2

答え

#include <iostream>
#include <string>
#include <cv.h>
#include <highgui.h>

const int ELEMENT = 2;
const std::string filename[ELEMENT]={"file1.jpg","file2.jpg"};

/********** プロトタイプ宣言 *************/
unsigned int Get_Ssd(IplImage *imgA,IplImage *imgB);


/*************** ここからメイン関数 ****************/
int main()
{

	//画像の読み込み
	IplImage *imgA[ELEMENT];
	for(int loop = 0; loop < ELEMENT; ++loop)
	{
		imgA[loop] = cvLoadImage( filename[loop].c_str(), CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
		if(imgA[loop] == NULL)
		{
			std::cerr << filename[loop] <<" : Can't Load file \n";
			for(int i = 0; i < loop ;++i) 
			{
				cvReleaseImage(&imgA[i]); //読み込んだ分のメモリを解放
			}
			exit(EXIT_FAILURE);
		}
	}


	//表示する
	for(int loop = 0; loop < ELEMENT; ++loop)
	{
		cvNamedWindow(filename[loop].c_str(),CV_WINDOW_AUTOSIZE);
		cvShowImage(filename[loop].c_str(),imgA[loop]);
	}

	std::cout << "SSD : " << Get_Ssd(imgA[0],imgA[1]);

	cvWaitKey(0); // 0秒待つ => ずっと入力待ち


	for(int loop = 0; loop < ELEMENT; ++loop)
	{
		cvReleaseImage( &imgA[loop] );
	}

	cvDestroyAllWindows();


	return EXIT_SUCCESS;
}


/*********** ここから各種関数***********/
unsigned int Get_Ssd(IplImage *imgA,IplImage *imgB)
{

	IplImage *tmpA = cvCreateImage(cvGetSize(imgA),IPL_DEPTH_64F,imgA->nChannels);
	cvScale(imgA,tmpA);

	IplImage *tmpB = cvCreateImage(cvGetSize(imgB),IPL_DEPTH_64F,imgB->nChannels);
	cvScale(imgB,tmpB);

	IplImage *tmp = cvCloneImage(tmpA);
	cvSub(tmpA,tmpB,tmp);
	cvPow(tmp,tmp,2);

	CvScalar SumData = cvScalarAll( 0 );
	SumData = cvSum(tmp);
	
	cvReleaseImage(&tmpA);
	cvReleaseImage(&tmpB);
	cvReleaseImage(&tmp);
	
	return cvRound(SumData.val[0] + SumData.val[1] + SumData.val[2] + SumData.val[3]);
}

メモ


結果が0に近いほど、類似している。
0の場合は完全一致を意味する。