OpenCVを使って輪郭を表示してみる

前回と前々回につかった白い部分を拡大する方法と黒い部分を拡大する方法を組み合わせて
Lenaさんの輪郭を浮かびあがせる。白色拡大のLenaさんから黒色拡大のLenaさんを引いてみる
と、あら不思議輪郭が出てきた。つまり輝度の変換の大きいところが白くなっている。

//画面をだすよ
void display(cv::Mat image) {
    //前の記事を参考
}

//受け取ったピクセル位置の八方のなかで一番数値が小さいピクセルの数字を求める
//Dilation 3x3
uchar getMin(cv::Mat image, int y, int x) {
    //前の記事を参考
}

//受け取ったピクセル位置の八方のなかで一番数値が大きいピクセルの数字を求める
//Erosion 3x3
uchar getMax(cv::Mat image, int y, int x) {
    //前の記事を参考
}

//
// ここから
//
int main(int argc, char** argv) {
    //lenaさん登場!!
    cv::Mat lena = cv::imread("lena.jpg");
    //lenaさん白黒レトロ
    cv::cvtColor(lena, lena, CV_RGB2GRAY);

    //lenaさんと同じサイズの画像
    int cols = lena.cols;
    int rows = lena.rows;
    cv::Mat tmp    = cv::Mat::zeros(cols, rows, CV_8UC1);
    cv::Mat tmp2   = cv::Mat::zeros(cols, rows, CV_8UC1);
    cv::Mat image  = cv::Mat::zeros(cols, rows, CV_8UC1);
    cv::Mat image2 = cv::Mat::zeros(cols, rows, CV_8UC1);
    cv::Mat image3 = cv::Mat::zeros(cols, rows, CV_8UC1);

    image  = lena.clone();
    image2 = lena.clone();
    uchar change;
    uchar change2;
    for (int t = 0; t < 1; t++) {
        for (int j = 2; j < rows - 2; j++) {
            for (int i = 2; i < cols - 2; i++) {
                change  = getMax(image,j,i);
                change2 = getMin(image2,j,i);
                tmp.at<uchar>(j, i) = cv::saturate_cast<uchar>(change);
                tmp2.at<uchar>(j, i) = cv::saturate_cast<uchar>(change2);
            }
        }
        image = tmp.clone();
        image2 = tmp2.clone();
    }

    for (int j = 2; j < rows - 2; j++) {
        for (int i = 2; i < cols - 2; i++) {
            //明るい画像から暗い画像を引く
            change = image.at<uchar>(j, i) - image2.at<uchar>(j, i);
            tmp.at<uchar>(j, i) = cv::saturate_cast<uchar>(change);
        }
    }
    image3 = tmp.clone();

    //画面に出して!!
    display(image3);
}

f:id:treehitsuji:20150118142431p:plain

輪郭Lenaさん

f:id:treehitsuji:20150208172606p:plain