OpenCVのまとめ

OpenCVのまとめ

自分の勉強用にリンクをまとめたものです。

OpenCVのバージョンについて

OpenCVのバージョンについては以下のリンクを見る。
OpenCVとは? 最新3.0の新機能概要とモジュール構成

OpenCV逆引きリファレンス

OpenCVでやりたいことが決まっている場合は以下のリンクを見る。
OpenCV逆引きリファレンス

Matの基本処理

OpenCV 1.x には,基本的に C言語 および Python のインタフェースが用意されていましたが,OpenCV 2.0 以降では,新たに C++ インタフェースが追加されました. OpenCV 1.x では,画像を管理する構造体として IplImage が,その他の行列を管理する構造体として CvMat が用いられました. しかし,OpenCV 2.x の C++ インタフェースでは, cv::Mat クラスを利用して,これらを統一的に扱います. cv::Mat クラスは,実際のデータへのポインタと,様々なプロパティ(幅,高さ,ビット深度など)を保持します.
cv::Matの基本処理

C++版 OpenCVの基本

OpenCVはライブラリの一つです。したがって、C++のソースコード内でOpenCVを使うためには、ヘッダファイルをインクルードして名前空間を指示しなければなりません。基本的にはインクルードするのは2つですが、OpenCVのより多くの機能を使う場合にはインクルードファイルの数が増えることがあります。標準ライブラリでusing namespace std; としたように、OpenCVではプログラムの最初にusing namespace cv; と書く必要があります。
C++版 OpenCVの基本

Matに画像を読み込む

imread関数を使います。2つ目の引数にはカラーで読み込むならIMREAD_UNCHANGEDを、グレースケールで読み込むならIMREAD_GRAYSCALEを指定します。
Matに画像を読み込む

Matの画像を表示させる

imshow関数を使います。1つ目の引数にウィンドウの名前、2つ目の引数に表示したいMatの名前を指定します。
画像の表示

グレースケール化する

cvtColor関数でグレースケール化できます。第一引数にカラー画像のMatを、第二引数にグレースケール画像を入れるためのMatを、第三引数にCV_BGR2GRAYを指定します。
グレースケール化する

画像の書き出し

imwrite関数で画像を保存できます。第一引数に出力する場所へのパスを指定します。拡張子はpng、jpgなどが可能です。Mat型のimgに対して下のようにして画像を書き出せます。
画像の書き出し

VS2010にOpenCV2.4.9をインストール

VisualStudioにOpenCVをインストールしたいとき↓
VS2010にOpenCV2.4.9をインストール

ライブラリパスの設定

リンクには、opencvの関数の場所または実態を示したLIBファイルが必要です。
ライブラリパスの設定

OpenCV_ CV_8UC1 から CV_8UC3 に変換する

チャンネル数 1 から チャンネル数 3 に変換したいとき。つまり、グレー画像からカラーに変換したいとき。

OpenCV_ CV_8UC1 から CV_8UC3 に変換する

基礎概念とOpenCVの導入(IplImage)

画像処理の考え方について理解したいとき↓

基礎概念とOpenCVの導入

IplImage構造体について

IplImageの構造について知りたくなったとき↓

【OpenCV】IplImage構造体

IplImageを定義する

・ファイルから確保する場合
IplImage* src_img = cvLoadImage(“TestImage.bmp”,CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);

・新規に画像データを確保する場合
IplImage* src_img = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3); 

16ビット画像を生成する

16ビット画像を使いたくなったとき↓

16ビット画像を生成する

IplImage* img = cvCreateImage(cvSize(500, 500), IPL_DEPTH_16U, 1);

for (int x = 0; x < img->width; x++)
{
for (int y = 0; y < img->height; y++)
{
cvSetReal2D(img, y, x, 65535 * (sqrt(pow(250-x, 2) + pow(250-y, 2)) / 500));
}
}

cvSaveImage(“16bit.png”, img);

OpenCVで細線化

OpenCVで細線化したいとき(C++)。詳細は下記サイトを参照。

opencvで細線化

#include <opencv2/imgproc/imgproc_c.h>
#include <opencv2/highgui/highgui_c.h>

void thinningIte(IplImage *Img_nichi, int pattern){
    IplImage *Img_sai = cvCreateImage(cvGetSize(Img_nichi), IPL_DEPTH_8U, 1);
    CvScalar ones = {1};
    cvSet(Img_sai, ones, NULL);

    for (int y = 1; y<Img_nichi->height - 1; y++){
        for (int x = 1; x<Img_nichi->width - 1; x++){
            int v9, v2, v3;
            int v8, v1, v4;
            int v7, v6, v5;

            v1 = CV_IMAGE_ELEM(Img_nichi, uchar, y + 0, x + 0);
            v2 = CV_IMAGE_ELEM(Img_nichi, uchar, y - 1, x + 0);
            v3 = CV_IMAGE_ELEM(Img_nichi, uchar, y - 1, x + 1);
            v4 = CV_IMAGE_ELEM(Img_nichi, uchar, y + 0, x + 1);
            v5 = CV_IMAGE_ELEM(Img_nichi, uchar, y + 1, x + 1);
            v6 = CV_IMAGE_ELEM(Img_nichi, uchar, y + 1, x + 0);
            v7 = CV_IMAGE_ELEM(Img_nichi, uchar, y + 1, x - 1);
            v8 = CV_IMAGE_ELEM(Img_nichi, uchar, y + 0, x - 1);
            v9 = CV_IMAGE_ELEM(Img_nichi, uchar, y - 1, x - 1);

            int S = (v2 == 0 && v3 == 1) + (v3 == 0 && v4 == 1) +
                    (v4 == 0 && v5 == 1) + (v5 == 0 && v6 == 1) +
                    (v6 == 0 && v7 == 1) + (v7 == 0 && v8 == 1) +
                    (v8 == 0 && v9 == 1) + (v9 == 0 && v2 == 1);

            int N = v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9;

            int m1 = 0, m2 = 0;

            if (pattern == 0) m1 = (v2 * v4 * v6);
            if (pattern == 1) m1 = (v2 * v4 * v8);

            if (pattern == 0) m2 = (v4 * v6 * v8);
            if (pattern == 1) m2 = (v2 * v6 * v8);

            if (S == 1 && (N >= 2 && N <= 6) && m1 == 0 && m2 == 0)
                CV_IMAGE_ELEM(Img_sai, uchar, y, x) = 0;
        }
    }
    cvAnd(Img_nichi, Img_sai, Img_nichi, NULL);
    cvReleaseImage(&Img_sai);
}

IplImage *thinning(IplImage *Img_1){
    IplImage *white = cvCreateImage(cvGetSize(Img_1), IPL_DEPTH_8U,1);
    CvScalar full_bits = {0xff};
    cvSet(white, full_bits, NULL);

    IplImage *Img_2 = cvCloneImage(Img_1);
    cvDiv(Img_2, white, Img_2, 1);

    IplImage *prev = cvCreateImage(cvGetSize(Img_2), IPL_DEPTH_8U, 1);
    IplImage *diff = cvCreateImage(cvGetSize(Img_2), IPL_DEPTH_8U, 1);

    do {
        thinningIte(Img_2, 0);
        thinningIte(Img_2, 1);
        cvAbsDiff(Img_2, prev, diff);
        cvCopy(Img_2, prev, NULL);
    } while (cvCountNonZero(diff) > 0);

    cvMul(Img_2, white, Img_2, 1);

    cvReleaseImage(&white);
    cvReleaseImage(&diff);
    cvReleaseImage(&prev);
    return Img_2;
}

int main(int argc, char* argv[]){
    if (argc < 2) return 1;

    IplImage *Img_orig; //元画像
    IplImage *Img_gray; //グレースケール
    IplImage *Img_nichi; //2値
    IplImage *Img_sai;

    int W, H; //widthとheight

    //画像の読み込み
    Img_orig = cvLoadImage(argv[1], 1);

    W = Img_orig->width;//幅
    H = Img_orig->height;//高さ

    //画像リソースの確保
    Img_gray  = cvCreateImage(cvSize(W, H), IPL_DEPTH_8U, 1); //白黒
    Img_nichi = cvCreateImage(cvSize(W, H), IPL_DEPTH_8U, 1); //白黒

    //グレースケール化
    cvCvtColor(Img_orig, Img_gray, CV_BGR2GRAY);

    //2値化
    cvThreshold(Img_gray, Img_nichi, 10, 255, CV_THRESH_BINARY);

    //細線化
    Img_sai = thinning(Img_nichi);

    //画像の表示
    cvShowImage("元画像", Img_orig);
    cvShowImage("グレースケール", Img_gray);
    cvShowImage("2値 (細線化前)", Img_nichi);
    cvShowImage("2値 (細線化後)", Img_sai);

    //画像の保存
    cvSaveImage("No_5a.bmp", Img_gray, 0);
    cvSaveImage("No_5b.bmp", Img_nichi, 0);
    cvSaveImage("No_5c.bmp", Img_sai, 0);

    //キー入力待機
    cvWaitKey(0);

    //ウィンドウの破棄
    cvDestroyAllWindows();

    //画像リソースの解放
    cvReleaseImage(&Img_orig);
    cvReleaseImage(&Img_gray);
    cvReleaseImage(&Img_nichi);
    cvReleaseImage(&Img_sai);

    return 0;
}

 

画像処理カテゴリの最新記事