Hough変換による直線/円の検出

Hough変換による直線/円の検出例です。円の検出では、処理の高速化のため、指定した半径の円のみを検出するようになっています。Hough変換では、2値化のアルゴリズムにより検出の精度が異なるため、画像の種類により、toBin() 関数内のアルゴリズムを様々に変更してみて下さい。

元画像   線の検出   円の検出
(半径125[pixel]の円)
   

実行ファイルのダウンロード: hough_proc.exe

 ダウンロード

Hough変換による直線/円の検出(hough_proc.cpp)
//-----------------------------------------------------------------
// 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);
}
inserted by FC2 system