Created
August 5, 2010 09:24
-
-
Save peccu/509475 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // #include "cv.h" | |
| // #include "highgui.h" | |
| #include <cv.h> | |
| #include <highgui.h> | |
| #include <math.h> | |
| // デバッグ出力 | |
| //#define DEBUG 1 | |
| // 縮小後の画像を表示するかどうか | |
| // #define DOUBLE 1 | |
| int canny1 = 100,canny2 = 200; | |
| int inc = 10; | |
| /* 2次元の点を上から下,左から右へソートする */ | |
| static int cmp_func( const void* _a, const void* _b, void* userdata ){ | |
| CvPoint* a = (CvPoint*)_a; | |
| CvPoint* b = (CvPoint*)_b; | |
| int y_diff = a->y - b->y; // aの方が下で正 | |
| int x_diff = a->x - b->x; // aの方が右で正 | |
| return y_diff ? x_diff : y_diff; // 左右の位置が同じなら上下の差を返す | |
| } | |
| // キーボード入力コールバック | |
| void keyboardFunc(unsigned char key){ | |
| //fprintf(stderr,"key = %c\n", key); | |
| switch (key) { | |
| case 'q': | |
| case 'Q': | |
| case '\033': // '\033' は ESC の ASCII コード | |
| exit(0); | |
| break; | |
| case 0: // ↑ | |
| canny1+= inc; | |
| fprintf(stderr,"key = ↑\n"); | |
| fprintf(stdout,"canny1(%d)++canny2(%d)\n",canny1,canny2); | |
| break; | |
| case 1: // ↓ | |
| canny1-= inc; | |
| fprintf(stderr,"key = ↓\n"); | |
| fprintf(stdout,"canny1(%d)--canny2(%d)\n",canny1,canny2); | |
| break; | |
| case 2: // ← | |
| canny2+= inc; | |
| fprintf(stderr,"key = ←\n"); | |
| fprintf(stdout,"canny1(%d) canny2(%d)++\n",canny1,canny2); | |
| break; | |
| case 3: // → | |
| canny2-= inc; | |
| fprintf(stderr,"key = →\n"); | |
| fprintf(stdout,"canny1(%d) canny2(%d)--\n",canny1,canny2); | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| int main(int argc, char** argv){ | |
| // カメラからのキャプチャ->frame | |
| CvCapture* capture = 0; | |
| IplImage* frame; // OpenCVからのキャプチャ画像 | |
| int capture_width, capture_height; | |
| int window_width = 640,window_height = 480; // 縮小後のサイズ | |
| int window_x = 100,window_y = 100; // ウィンドウの位置 | |
| // capture = cvCaptureFromCAM(0); // 内蔵カメラ | |
| capture = cvCaptureFromCAM(1); // USBカメラ.なければ内蔵カメラ | |
| if (capture){ | |
| // キャプチャ | |
| frame = cvQueryFrame(capture); | |
| // // 画像をファイルからグレースケールで読み込む | |
| // img = cvLoadImage(imgfile, CV_LOAD_IMAGE_GRAYSCALE); | |
| // カメラのキャプチャ領域サイズを取得 | |
| capture_width = (int)( cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH) ); | |
| capture_height = (int)( cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT) ); | |
| } else { | |
| fprintf(stderr,"Could not initialize capturing...\n"); | |
| return -1; | |
| } | |
| // 画像のサイズが大きい時に縮小するための領域作成 | |
| printf("w:h = %d:%d\n",capture_width,capture_height); | |
| IplImage* resize; | |
| if((capture_width>window_width)||(capture_height>window_height)){ | |
| CvSize smallSize = cvSize(window_width,window_height); | |
| resize = cvCreateImage(smallSize, frame->depth, frame->nChannels); | |
| }else{ | |
| resize = frame; | |
| } | |
| // ハフ変換で直線の抽出 | |
| IplImage* src = cvCreateImage(cvGetSize(resize), IPL_DEPTH_8U, 1); | |
| if( !src ) return -1; | |
| IplImage* dst; // キャニーによるエッジ画像用の領域 | |
| IplImage* color_dst; // 線を入れたカラー画像の領域 | |
| CvMemStorage* storage = cvCreateMemStorage(0); // ハフ変換で使うメモリ領域 | |
| CvSeq* lines = 0; // ハフ変換で取り出した線のシーケンス | |
| int i; // 線を描画する時の添字 | |
| char c; // キー入力を受け取る | |
| //ウインドウ生成 | |
| // 画像サイズにウィンドウサイズを合わせ,固定する | |
| #ifdef DOUBLE | |
| cvNamedWindow( "Source", CV_WINDOW_AUTOSIZE ); | |
| cvMoveWindow( "Source",0,0); | |
| #endif | |
| cvNamedWindow( "Hough", CV_WINDOW_AUTOSIZE ); | |
| cvMoveWindow( "Hough", window_width,0); | |
| fprintf(stdout,"canny1(%d) canny2(%d)\n",canny1,canny2); | |
| // ハフラインのループ | |
| while(1){ | |
| // キャプチャ | |
| frame = cvQueryFrame(capture); | |
| // 画像のリサイズ | |
| cvResize(frame, resize); | |
| #ifdef DOUBLE | |
| cvShowImage( "Source", resize ); | |
| #endif | |
| // resize->srcでグレースケールに変換 | |
| cvCvtColor(resize, src, CV_BGR2GRAY); | |
| //画像領域の確保 | |
| // サイズ(高さと幅),色深度(色を何ビットで表現するか),チャネル | |
| // チャネル:グレースケール->1,RGB->3,RGB+αチャネル->4 | |
| dst = cvCreateImage( cvGetSize(resize), 8, 1 ); | |
| color_dst = cvCreateImage( cvGetSize(resize), 8, 3 ); | |
| // エッジ検出(Cannyアルゴリズム) | |
| // 二つの閾値+アパーチャサイズ | |
| // 閾値のうち大きい方を 強エッジ,小さい方を弱エッジ | |
| // 強→エッジ検出しやすさ(小さいと点がいっぱい.大きいと線が少し) | |
| // 弱→つながっているかどうかの判定 | |
| // cvCanny( src, dst, canny1, canny2, 3 ); | |
| cvCanny( src, dst, 150, 200, 3 ); | |
| //エッジ画像をカラー化 | |
| cvCvtColor( dst, color_dst, CV_GRAY2BGR ); | |
| //ハフ変換で直線検出 | |
| // cvHoughLines2(入力画像, 検出された線を保存する領域, | |
| // ハフ変換の種類(確率的ハフ変換), | |
| // 距離解像度(1ピクセル当たりの単位), | |
| // 角度解像度(ラジアン単位), | |
| // しきい値(これよりも大きい時に線となる), | |
| // 最小の線の長さ, | |
| // 同一線上に存在する線分とする二つの最大の間隔, ) | |
| lines = cvHoughLines2( dst, storage, | |
| CV_HOUGH_PROBABILISTIC, | |
| 1, // 解像度 | |
| CV_PI/180, 100, // 角度,閾値 | |
| 50, 10 ); // 最短長,最大間隔 | |
| printf("\x1b[2J"); // 画面クリアするエスケープ文字 | |
| printf("\x1b[2Jbefore sort\n"); | |
| // ユーザーデータってなんや | |
| cvSeqSort( lines, cmp_func, 0 /* ここではユーザーデータは使用しない */ ); | |
| printf("after sort\n"); | |
| if(lines->total != 0){ | |
| int diff = 256/lines->total; | |
| int r,b,g; | |
| //検出した直線を描く | |
| for( i = 0; i < lines->total; i++ ){ | |
| CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i); | |
| // 255-i*diff | |
| if(line[0].x<window_width/2){ | |
| r = i*diff; | |
| g = 0; | |
| b = 0; | |
| printf("left %2d:%4d,%4d,%4d,%4d\n",i,line[0].x,line[0].y,line[1].x,line[1].y); | |
| // ラケットかどうかの判定はどうしようか.平均? | |
| }else{ | |
| r = 0; | |
| g = 0; | |
| b = i*diff; | |
| printf(" right %2d:%4d,%4d,%4d,%4d\n",i,line[0].x,line[0].y,line[1].x,line[1].y); | |
| } | |
| // ここでろうでんさんの方に渡せばいいはず | |
| cvLine( color_dst, line[0], line[1], CV_RGB(r,g,b), 3, CV_AA, 0 ); | |
| } | |
| }else{ | |
| printf("no line\n"); | |
| } | |
| // ウィンドウに表示 | |
| cvShowImage( "Hough", color_dst ); | |
| // 終了キー入力待ち | |
| // c = cvWaitKey(200); // ms秒入力を待つ | |
| c = cvWaitKey(10); // 入力を待つ | |
| if( c >= 0 ){ | |
| //fprintf(stderr,"key = %d, %c, \n", c, c); | |
| if ((c == 'q')||(c == 'Q')||(c == '\033')){ | |
| break; | |
| } | |
| keyboardFunc(c); | |
| } | |
| #ifdef DEBUG | |
| break; | |
| #endif | |
| } | |
| #ifdef DEBUG | |
| // 0 = 無限秒キー入力を待つ | |
| cvWaitKey(0); | |
| #endif | |
| // メモリ開放(と思う) | |
| cvReleaseImage(&frame); | |
| cvReleaseImage(&src); | |
| cvReleaseImage(&dst); | |
| cvReleaseImage(&color_dst); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment