Hough変換による直線/円の検出例です。円の検出では、処理の高速化のため、指定した半径の円のみを検出するようになっています。Hough変換では、2値化のアルゴリズムにより検出の精度が異なるため、画像の種類により、toBin() 関数内のアルゴリズムを様々に変更してみて下さい。
元画像 | 線の検出 | 円の検出 (半径125[pixel]の円) |
||
実行ファイルのダウンロード: hough_proc.exe
//----------------------------------------------------------------- // hough_proc.cpp: // Hough変換用関数 (直線検出, 円検出) // Last Update: <2004/12/10 09:56:39 A.Murakami> //----------------------------------------------------------------- #include <windows.h> #include "wingui.h" #include "ipcommon.h" #include "binalize.h" #include "hough.h" //----------------------------------------------------------------- extern UINT iHeight,iWidth,iLength,iSize;// 高さ,幅,1ラインの長さ,サイズ extern LPBYTE lpOrgBMP,lpBMP; // オリジナル画像, 表示画像 //----------------------------------------------------------------- #define CIR_RADIUS 125 // 円の半径 LPBYTE iBin; // 2値画像用 //----------------------------------------------------------------- void toOrg(); void toBin(); void Extract_Line(); void Extract_cir(); //----------------------------------------------------------------- // メニューへの追加内容 //----------------------------------------------------------------- MenuInfo MI[] = { {"元画像 ",toOrg}, {"2値化 ",toBin}, {"線検出 ",Extract_Line}, {"円検出 ",Extract_cir}, {NULL,NULL} }; //----------------------------------------------------------------- // 元画像の表示 //----------------------------------------------------------------- void toOrg() { CopyMemory(lpBMP,lpOrgBMP,iLength*iHeight); } //----------------------------------------------------------------- // 2値画像の表示 //----------------------------------------------------------------- void toBin() { int sobel_x[9] = { // ソーベルフィルタ[横] -1, 0, 1, -2, 0, 2, -1, 0, 1 }; int sobel_y[9] = { // ソーベルフィルタ[縦] -1, -2, -1, 0, 0, 0, 1, -2, -1 }; LPBYTE iTemp = GetGray(); iBin = GetGray(); // 空間フィルタ適用 spacial_filtering(iBin ,sobel_x,0.5); spacial_filtering(iTemp,sobel_y,0.5); // 2値化 GrayToBin(iBin ,BW_BKG_AUTO); GrayToBin(iTemp,BW_BKG_AUTO); // 縦横/画像の加算 IPfunc_OR(iBin,iTemp); // 表示用 GrayToColor(iBin,lpBMP); } //----------------------------------------------------------------- // 画像中から線の抽出 //----------------------------------------------------------------- void Extract_Line() { // 2値化画像の取得 toBin(); CopyMemory(lpBMP,lpOrgBMP,iLength*iHeight); //-------------------------------------------------- // Hough 変換実行/表示 //-------------------------------------------------- // 0.25: 検出尺度[0..1] // オプション: // HOUGH_LINE_MC : m(傾き),c(切片) 空間への写像 // [傾き∞の問題に対処したもの] // HOUGH_LINE_RTH: ρ(距離),θ(角度) 空間への写像 LHough_proc(iBin,0.25,HOUGH_LINE_MC); // 後片付け GlobalFree(iBin); } //----------------------------------------------------------------- // 画像中から円の抽出 //----------------------------------------------------------------- void Extract_cir() { int cir_n; POINT cir_p[100]; // 2値化画像の取得 toBin(); //-------------------------------------------------- // Hough 変換実行 //-------------------------------------------------- // cir_p: 円の検出位置 // CIR_RADIUS: 円の半径 // 100: 最大検出数 // 0.5: 検出尺度[0..1] cir_n = CHough_proc(iBin,cir_p,CIR_RADIUS,100,0.5); // 表示 TCHAR msg[512]; wsprintf(msg,"%d circle found.",cir_n); MessageBox(NULL,msg,0,0); draw_hough_cir(lpBMP,cir_n,cir_p,CIR_RADIUS); // 後片付け GlobalFree(iBin); } |