はてなブックマークに追加

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
はてなブックマークに追加

DCT変換と逆DCT変換

openCVを使ってDCT変換と逆DCT変換するサンプルソースです。 cvDCTを使用した場合、画像中心に高周波成分が表示され、周辺に向かうにつれて低周波成分になっていきます。 したがって、下図に示すフィルタはどちらも低周波成分を通し高周波成分をカットするローパスフィルタとして 機能します。左側のフィルタは理想的なLPF、右側のフィルタはガウシアンフィルタになります。

opencv3.jpg

下図に理想LPFとガウシアンフィルタを使用したそれぞれの場合の結果を示します。理想LPFを使用した場合 周波数ドメインの関数に不連続な部分ができてしまうため、変換後の画像にリンギングが生じています。 それに対してガウシアンフィルタを使用した場合には、フィルタ関数が連続関数で記述可能なため、リンギングは生じていません。(ガウシアンの係数によっては生じる場合もある)

opencv4.jpg
ピクセルにアクセスするためのマクロ定義はこちら。ピクセルアクセスのためのマクロ
int main(int argc, char ** argv)
{
	IplImage *invImage;
	CvMat *dct,*idct;
	
	IplImage *image = cvLoadImage("lena.jpg", CV_LOAD_IMAGE_GRAYSCALE);
	IplImage *mask = cvLoadImage("mask1.jpg", CV_LOAD_IMAGE_GRAYSCALE);
	invImage = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1);

	dct = cvCreateMat(image->height, image->width, CV_64FC1);
	idct = cvCreateMat(image->height, image->width, CV_64FC1);
	
	// DCT
	int x, y;
	for(y=0; yheight; y++){
		for(x=0; xwidth; x++){
			cvmSet(dct,
				   y,
				   x,
				   (double)(unsigned char)(image->imageData[image->widthStep
															* y + x]));
		}
	}
	
	cvDCT( dct, dct, CV_DXT_FORWARD);
	
	// マスク値をDCT結果に乗算
	for(int x = 0; x < dct->width; ++x){
		for(int y = 0; y < dct->height; ++y){
			double scale = PIXVAL(mask, x, y) / 255.0;
			double value = cvmGet(dct, y, x) * scale;
			cvmSet(dct, y, x, value);
		}
	}
	
	// 逆変換
	cvDCT( dct, idct, CV_DXT_INVERSE);
	for(y=0; yheight; y++){
		for(x=0; xwidth; x++){
			invImage->imageData[invImage->widthStep * y + x] = cvmGet(idct,y,x);
		}
	}

	cvWaitKey(0);
	return 0;
}
スポンサーサイト

コメントの投稿

非公開コメント

開発アプリ

iDOF 色影 ラテアート ぱすてる

プロフィール

hokuson

Author:hokuson
京都在住。iPhoneアプリ「色影」や「iDOF」の開発者。アプリのレビューとかもしてみる。博士後期課程@R大学。ついに就職活動なるものをしなければいけないらしい。誰か雇ってください。笑。

カレンダー
06 | 2017/07 | 08
- - - - - - 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 - - - - -
カテゴリ
最新コメント
RSSリンクの表示
リンク
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。