コピーと充填
作成者: 上田悦子, 最終変更者: 怡土順一, 最終変更リビジョン: 362, 最終変更日時: 2008-01-28 13:12:09 +0900 (月, 28 1月 2008)
■ コピー
OpenCVには基本機能として,ある配列(画像)を別の配列(画像)にコピーするという関数がある. 単純に配列全体をコピーする以外に,マスクを指定することで,特定の領域だけをコピーする事も出来る. コピー元配列とコピー先配列は,同じ型,同じ次元,同じサイズでなければならないという制限を持つ.サンプル
画像のコピー cvCopy
コピー先の画像を二値化してマスク領域を作成した上で,コピー元画像をコピー先画像にコピーする
サンプルコード
#include <cv.h> #include <highgui.h> int main (int argc, char **argv) { IplImage *src_img = 0, *dst_img = 0; IplImage *cpy_img, *dst_img_gray, *msk_img; // (1)画像を読み込む if (argc != 3 || (src_img = cvLoadImage (argv[1], CV_LOAD_IMAGE_COLOR)) == 0 || (dst_img = cvLoadImage (argv[2], CV_LOAD_IMAGE_COLOR)) == 0) return -1; cpy_img = cvCloneImage (dst_img); if (src_img->width != dst_img->width) return -1; if (src_img->height != dst_img->height) return -1; // (2)dst_imgの画像のRedのプレーンだけを2値化してマスクを作成する dst_img_gray = cvCreateImage (cvGetSize (dst_img), IPL_DEPTH_8U, 1); cvSplit (dst_img, NULL, NULL, dst_img_gray, NULL); msk_img = cvCloneImage (dst_img_gray); cvSmooth (dst_img_gray, dst_img_gray, CV_GAUSSIAN, 5); cvThreshold (dst_img_gray, msk_img, 0, 255, CV_THRESH_BINARY_INV | CV_THRESH_OTSU); // (3)src_imgをdst_imgにコピーする.マスキングされている部分は元の値が保持される. cvCopy (src_img, cpy_img, msk_img); // (4)結果を表示する cvNamedWindow ("src", CV_WINDOW_AUTOSIZE); cvNamedWindow ("dst", CV_WINDOW_AUTOSIZE); cvNamedWindow ("mask", CV_WINDOW_AUTOSIZE); cvNamedWindow ("copy", CV_WINDOW_AUTOSIZE); cvShowImage ("src", src_img); cvShowImage ("dst", dst_img); cvShowImage ("mask", msk_img); cvShowImage ("copy", cpy_img); cvWaitKey (0); cvDestroyWindow ("src"); cvDestroyWindow ("dst"); cvDestroyWindow ("mask"); cvDestroyWindow ("copy"); cvReleaseImage (&src_img); cvReleaseImage (&dst_img); cvReleaseImage (&msk_img); cvReleaseImage (&cpy_img); cvReleaseImage (&dst_img_gray); return 1; }
// (1)画像を読み込む
コマンド引数で指定されたファイル名の画像(コピー元画像)をオープンし,関数
cvLoadImage()で読み込む.2番目の引数にCV_LOAD_IMAGE_COLORを指定することで,
デプス8ビット,3チャンネルのカラー画像として読み込む.
同様に2番目の引数で指定されたファイル名の画像(コピー先画像)も読み込む.
画像のサイズが同じであるかを確認しておく.
// (2)dst_imgの画像のRedのプレーンだけを二値化してマスクを作成する
コピー先画像であるdst_imgを2値化し,その結果をマスキング画像とする.
実行例のように人間の肌色を分離する際には,カラープレーンに着目するときれいに分離する事が出来る.
この例では単純に,Redのプレーンだけを抽出しそのプレーンに対して,二値化を行なっている.
二値化方法の詳細については画像の二値化 cvThreshold, cvAdaptiveThresholdを参照の事.
// (3)src_imgをdst_imgにコピーする.マスキングされている部分は元の値が保持される.
関数cvCopy()を用いて,マスク領域を考慮した画像のコピーを行なう.
具体的には,以下のようにマスク画像の画素値が0でない領域のみコピー元画像がコピーされる.
mask(I)!=0 の場合、dst(I)=src(I)
// (4)結果を表示する
形状を変換した画像を表示し,何かキーが押されるまで待つ.
実行結果例
コピー元画像 | コピー先画像 | マスク画像 | コピー結果 |