- 2008-01-09 (水) 1:19
概要
- OpenCVの顔検出モジュール使って作ってみたやつを、お蔵出し。
- 色情報は使ってない。だからチェ・ゲバラも検出可能(下図参照)。
- 動作環境はXPが快適に動くぐらい。なかなかシビアです。でも精度はさすが。
- 特別なことはやってないんで、ソース公開します。Linuxでもコンパイルできるはず。画像を入れ替えて他の誰かを模倣するなり、好きに使ってください。
- (2007.02.25 — 一部改変)
- 元ネタはこちらです。神!→工学ナビ
- 元ネタの元ネタはこちら。神!→攻殻機動隊 STAND ALONE COMPLEX The Laughing Man
スクリーンショット
「撃て!臆病者め!」 チェ・ゲバラさん模倣前
「残念ながら僕、野球が下手ですから」 チェ・ゲバラさん模倣中
動画
downloads
ソースコード(laugh.cpp)
////////////////////////////////////////////////////////////////////////////////
// 『笑い男模倣ツール Catcher in the Rye』の模倣ツール
// コバヤシマサヨシ 2006.7.31
// 一部変更 - 2007.02.25
//
// 参照URL:
// http://www1.bbiq.jp/kougaku/koukaku.html (元ネタ)
// http://www.kokaku-s.com/tlm/index.html (元ネタの元ネタ)
////////////////////////////////////////////////////////////////////////////////
//==============================================================================
//インクルード
//==============================================================================
#include <stdio .h>
//OpenCVヘッダ
#include "cv.h"
#include "highgui.h"
//OpenCVライブラリ
#pragma comment (lib, "cv.lib")
#pragma comment( lib, "cxcore.lib")
#pragma comment( lib, "highgui.lib")
//==============================================================================
//グローバル
//==============================================================================
static CvMemStorage* storage = 0;
static CvHaarClassifierCascade* cascade = 0;
//------------------------------------------------------------------------------
// 指定画素のRGB値を取得する
//------------------------------------------------------------------------------
int getpixel(IplImage *image, int x, int y, int *r, int *g, int *b)
{
*r =(uchar) image->imageData[y *image->widthStep+ x * image->nChannels + 2];
*g =(uchar) image->imageData[y *image->widthStep+ x * image->nChannels + 1];
*b =(uchar) image->imageData[y *image->widthStep+x * image->nChannels];
return 0;
}
//——————————————————————————
// 指定画素にRGB値を代入する
//——————————————————————————
int setpixel(IplImage *image, int x, int y, int *r, int *g, int *b)
{
image->imageData[y *image->widthStep+ x * image->nChannels + 2] = *r;
image->imageData[y *image->widthStep+ x * image->nChannels + 1] = *g;
image->imageData[y *image->widthStep+x * image->nChannels] = *b;
return 0;
}
//——————————————————————————
// 顔を探索し,マスクを重ねる
//——————————————————————————
int FaceDetect(IplImage *img, IplImage *mask, IplImage *dst)
{
double scale = 1.5;
//処理に用いる画像を定義
IplImage* gray = cvCreateImage(cvSize(img->width,img->height), 8, 1);
IplImage* small_img = cvCreateImage(cvSize( cvRound (img->width/scale),
cvRound (img->height/scale)), 8, 1);
//前処理
cvCvtColor(img, gray, CV_BGR2GRAY);
cvResize(gray, small_img, CV_INTER_LINEAR);
cvEqualizeHist(small_img, small_img);
cvCopy(img, dst);
cvClearMemStorage(storage);
//顔を探索する
CvSeq* faces = cvHaarDetectObjects(small_img, cascade, storage,
1.1, 2, 0, cvSize(30, 30));
//発見した顔の数だけループ
for (int i=0; i< (faces ? faces->total : 0); i++) {
CvRect* face = (CvRect*)cvGetSeqElem(faces, i);
CvPoint center; //顔候補領域の中心座標
center.x = cvRound((face->x + face->width*0.5)*scale);
center.y = cvRound((face->y + face->height*0.5)*scale);
CvRect mask_size; //中心座標からマスクの位置を算出する
mask_size.x = center.x - (mask->width/2);
mask_size.y = center.y - (mask->height/2);
mask_size.width = center.x + (mask->width/2);
mask_size.height = center.y + (mask->height/2);
for(int x=mask_size.x; x<mask_size .width; x++) {
for (int y=mask_size.y; y<mask_size.height; y++) {
int red, green, blue;
//マスクの画素値を取得
getpixel(mask, x-mask_size.x, y-mask_size.y, &red, &green, &blue);
//緑色の画素は無視する
if (red==0 && green==255 && blue==0) {
continue;
}
setpixel(dst, x, y, &red, &green, &blue);
}
}
}
cvReleaseImage(&gray);
cvReleaseImage(&small_img);
return 0;
}
//——————————————————————————
//メイン
//——————————————————————————
int main( int argc, char** argv )
{
CvCapture* capture = 0;
IplImage *frame;
IplImage *frame_copy;
IplImage *result;
char window_name[] = "Catcher in the Rye";
const char* cascade_name = "haarcascade_frontalface_alt.xml"; //顔検出用のデータが入ってるXMLファイル
char mask_name[]="laughingman.bmp"; //マスク画像
//顔検出データを読み込む
cascade = (CvHaarClassifierCascade*)cvLoad(cascade_name, 0, 0, 0);
if (!cascade){ //読み込みに失敗したら終了
fprintf( stderr, "ERROR: Could not load classifier cascaden" );
return -1;
}
storage = cvCreateMemStorage(0); // メモリ確保
//カメラデバイスを開く
capture = cvCaptureFromCAM(0);
if (!capture) { //カメラが見つからなかったときは終了
fprintf(stderr, "ERROR: Found No Cameran");
return -1;
}
// ウインドウを開く
cvNamedWindow(window_name, 1);
//画像定義
frame = cvQueryFrame(capture);
frame_copy = cvCreateImage(cvGetSize(frame), 8, 3);
result = cvCreateImage(cvGetSize(frame), 8, 3);
//マスクを読み込む
IplImage* mask = cvLoadImage(mask_name);
// メインループ
while(1) {
//キャプチャ
frame = cvQueryFrame(capture);
//原点位置にあわせてコピーを行う
//この処理がないと上下が逆になってしまうことがある
if(frame->origin == IPL_ORIGIN_TL)
cvCopy(frame, frame_copy);
else
cvFlip(frame, frame_copy);
//顔検出→マークのインポーズ
FaceDetect(frame_copy, mask, result);
//キー入力で終了
if(cvWaitKey( 10 ) >= 0) {
break;
}
//ウインドウに表示する
cvShowImage(window_name, result);
}
//解放
cvReleaseCapture(&capture);
cvReleaseImage(&frame_copy);
cvReleaseImage(&result);
cvDestroyAllWindows();
return 0;
}
Comments:0
Trackback+Pingback:0
- TrackBack URL for this entry
- http://www.masayashi.com/labs/laughing_man/trackback
- Listed below are links to weblogs that reference
- 「笑い男模倣ツール」の模倣ツール from 王様の箱庭













