2値化(Binarization)

2値化というのは文字通り、画像の色情報を黒と白の2値に単純化する操作である。
画像処理、特に各種の認識処理では画像の情報が単純であればあるほど効率良く行えるので2値化は非常に重要である。

一般的には2値化のことを「モノクローム化」と考えるが(私もそうだった)実際にはモノクローム化した画像はいわゆる「グレイスケール」画像であり黒と白以外の色が含まれる。

    • グレイスケール化された画像

2値化はグレイスケール化された画像情報を閾値に則って文字通り黒と白の二色に分類する処理である。OpenCVでの2値化は

元画像のグレースケール化
グレースケール化した画像を閾値で2値化

という手順となる

    • OpenCVUtil.binarization
+ (IplImage*)binarize:(IplImage*)src threshold:(int)threshold
{
    IplImage *tmp = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
    IplImage *bin = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);

    /*	カラー画像をグレイスケール画像に変換  */
    cvCvtColor(src, tmp, CV_BGR2GRAY);
    
    /*グレイスケールを閾値で単純化*/
    cvThreshold(tmp, bin, threshold, 255, CV_THRESH_BINARY);

    cvReleaseImage(&tmp);
    return bin;
}
    • 処理結果(閾値128で2値化)

なお、実際にはcvThreshold実行前に画像のノイズを取り去る目的でcvSmoothによる平滑化を施すのがイディオムとなっている。(サンプル画像では違いが分からないので結果は省略する)

    • OpenCVUtil.binarization (平滑化を施した)
+ (IplImage*)binarize:(IplImage*)src threshold:(int)threshold
{
    IplImage *tmp = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
    IplImage *bin = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);

    /*	カラー画像をグレイスケール画像に変換  */
    cvCvtColor(src, tmp, CV_BGR2GRAY);

    /* 平滑化 */
    cvSmooth(tmp, bin, CV_MEDIAN, 3);
    cvCopy(bin, tmp);

    /* グレイスケールを閾値で単純化 */
    cvThreshold(tmp, bin, threshold, 255, CV_THRESH_BINARY);

    cvReleaseImage(&tmp);
    return bin;
}