手机版
你好,游客 登录 注册
背景:
阅读新闻

OpenCV 图像细化

[日期:2017-11-04] 来源:Linux社区  作者:hutiann [字体: ]

图像细化多用于机器人视觉,OCR字符识别等领域,细化后的图像经过去毛刺就成为了我们常说的图像的骨架。

该图像细化代码依据论文: T. Y. ZHANG and C. Y. SUEN  A Fast Parallel Algorithm for Thinning Digital Patterns

代码如下:

void ThinSubiteration1(Mat & pSrc, Mat & pDst) {
        int rows = pSrc.rows;
        int cols = pSrc.cols;
        pSrc.copyTo(pDst);
        for(int i = 0; i < rows; i++) {
                for(int j = 0; j < cols; j++) {
                        if(pSrc.at<float>(i, j) == 1.0f) {
                                /// get 8 neighbors
                                /// calculate C(p)
                                int neighbor0 = (int) pSrc.at<float>( i-1, j-1);
                                int neighbor1 = (int) pSrc.at<float>( i-1, j);
                                int neighbor2 = (int) pSrc.at<float>( i-1, j+1);
                                int neighbor3 = (int) pSrc.at<float>( i, j+1);
                                int neighbor4 = (int) pSrc.at<float>( i+1, j+1);
                                int neighbor5 = (int) pSrc.at<float>( i+1, j);
                                int neighbor6 = (int) pSrc.at<float>( i+1, j-1);
                                int neighbor7 = (int) pSrc.at<float>( i, j-1);
                                int C = int(~neighbor1 & ( neighbor2 | neighbor3)) +
                                                int(~neighbor3 & ( neighbor4 | neighbor5)) +
                                                int(~neighbor5 & ( neighbor6 | neighbor7)) +
                                                int(~neighbor7 & ( neighbor0 | neighbor1));
                                if(C == 1) {
                                        /// calculate N
                                        int N1 = int(neighbor0 | neighbor1) +
                                                        int(neighbor2 | neighbor3) +
                                                        int(neighbor4 | neighbor5) +
                                                        int(neighbor6 | neighbor7);
                                        int N2 = int(neighbor1 | neighbor2) +
                                                        int(neighbor3 | neighbor4) +
                                                        int(neighbor5 | neighbor6) +
                                                        int(neighbor7 | neighbor0);
                                        int N = min(N1,N2);
                                        if ((N == 2) || (N == 3)) {
                                                /// calculate criteria 3
                                                int c3 = ( neighbor1 | neighbor2 | ~neighbor4) & neighbor3;
                                                if(c3 == 0) {
                                                        pDst.at<float>( i, j) = 0.0f;
                                                }
                                        }
                                }
                        }
                }
        }
}


void ThinSubiteration2(Mat & pSrc, Mat & pDst) {
        int rows = pSrc.rows;
        int cols = pSrc.cols;
        pSrc.copyTo( pDst);
        for(int i = 0; i < rows; i++) {
                for(int j = 0; j < cols; j++) {
                        if (pSrc.at<float>( i, j) == 1.0f) {
                                /// get 8 neighbors
                                /// calculate C(p)
                            int neighbor0 = (int) pSrc.at<float>( i-1, j-1);
                            int neighbor1 = (int) pSrc.at<float>( i-1, j);
                            int neighbor2 = (int) pSrc.at<float>( i-1, j+1);
                            int neighbor3 = (int) pSrc.at<float>( i, j+1);
                            int neighbor4 = (int) pSrc.at<float>( i+1, j+1);
                            int neighbor5 = (int) pSrc.at<float>( i+1, j);
                            int neighbor6 = (int) pSrc.at<float>( i+1, j-1);
                            int neighbor7 = (int) pSrc.at<float>( i, j-1);
                                int C = int(~neighbor1 & ( neighbor2 | neighbor3)) +
                                        int(~neighbor3 & ( neighbor4 | neighbor5)) +
                                        int(~neighbor5 & ( neighbor6 | neighbor7)) +
                                        int(~neighbor7 & ( neighbor0 | neighbor1));
                                if(C == 1) {
                                        /// calculate N
                                        int N1 = int(neighbor0 | neighbor1) +
                                                int(neighbor2 | neighbor3) +
                                                int(neighbor4 | neighbor5) +
                                                int(neighbor6 | neighbor7);
                                        int N2 = int(neighbor1 | neighbor2) +
                                                int(neighbor3 | neighbor4) +
                                                int(neighbor5 | neighbor6) +
                                                int(neighbor7 | neighbor0);
                                        int N = min(N1,N2);
                                        if((N == 2) || (N == 3)) {
                                                int E = (neighbor5 | neighbor6 | ~neighbor0) & neighbor7;
                                                if(E == 0) {
                                                        pDst.at<float>(i, j) = 0.0f;
                                                }
                                        }
                                }
                        }
                }
        }
}

 

 

int main(int argc, char* argv[])
{
    Mat src = imread("D://thinning.png", 0);
    Mat inputarray = src(Rect(10, 10, src.cols - 20, src.rows - 20));
    threshold(inputarray, inputarray, 100, 255, CV_THRESH_BINARY);
    Mat outputarray(inputarray.rows,inputarray.cols,CV_32FC1);
   
    bool bDone = false;
    int rows = inputarray.rows;
    int cols = inputarray.cols;

    inputarray.convertTo(inputarray, CV_32FC1);

    inputarray.copyTo(outputarray);

    //outputarray.convertTo(outputarray, CV_32FC1);

    /// pad source
    Mat p_enlarged_src = Mat(rows + 2, cols + 2, CV_32FC1);
    for (int i = 0; i < (rows + 2); i++) {
        p_enlarged_src.at<float>(i, 0) = 0.0f;
        p_enlarged_src.at<float>(i, cols + 1) = 0.0f;
    }
    for (int j = 0; j < (cols + 2); j++) {
        p_enlarged_src.at<float>(0, j) = 0.0f;
        p_enlarged_src.at<float>(rows + 1, j) = 0.0f;
    }
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            if (inputarray.at<float>(i, j) >= 20.0f) {
                p_enlarged_src.at<float>(i + 1, j + 1) = 1.0f;
            }
            else
                p_enlarged_src.at<float>(i + 1, j + 1) = 0.0f;
        }
    }

    /// start to thin
    Mat p_thinMat1 = Mat::zeros(rows + 2, cols + 2, CV_32FC1);
    Mat p_thinMat2 = Mat::zeros(rows + 2, cols + 2, CV_32FC1);
    Mat p_cmp = Mat::zeros(rows + 2, cols + 2, CV_8UC1);

    while (bDone != true) {
        /// sub-iteration 1
        ThinSubiteration1(p_enlarged_src, p_thinMat1);
        /// sub-iteration 2
        //ThinSubiteration2(p_thinMat1, p_thinMat2);
        /// compare
        compare(p_enlarged_src, p_thinMat1, p_cmp, CV_CMP_EQ);
        /// check
        int num_non_zero = countNonZero(p_cmp);
        if (num_non_zero == (rows + 2) * (cols + 2)) {
            bDone = true;
        }
        /// copy
        p_thinMat1.copyTo(p_enlarged_src);
    }
    // copy result
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            outputarray.at<float>(i, j) = p_enlarged_src.at<float>(i + 1, j + 1);
        }
    }
    imshow("src", inputarray);
    imshow("dst", p_enlarged_src);
    waitKey(0);


    return 0;


}

 

附上效果图:

OpenCV官方教程中文版(For Python) PDF  http://www.linuxidc.com/Linux/2015-08/121400.htm

Ubuntu 14.04安装OpenCV2.4.9  http://www.linuxidc.com/Linux/2016-07/132884.htm

Ubuntu 16.04上用CMake图形界面交叉编译树莓派的OpenCV3.0 http://www.linuxidc.com/Linux/2016-10/135914.htm

Ubuntu 16.04中安装OpenCV 2.4.11  http://www.linuxidc.com/Linux/2016-07/132882.htm

Ubuntu 16.04下Matlab2014a+Anaconda2+OpenCV3.1+Caffe安装  http://www.linuxidc.com/Linux/2016-07/132860.htm

Linux上安装和编译OpenCV3.0.0  http://www.linuxidc.com/Linux/2017-07/145446.htm

Ubuntu 16.04下OpenCV安装笔记和例程 http://www.linuxidc.com/Linux/2017-08/146027.htm

Ubuntu 16.04下TensorFlow+Caffe+OpenCV3.1+Theano部署  http://www.linuxidc.com/Linux/2017-01/139503.htm

Ubuntu 16.04 编译安装OpenCV 3.1及OpenCV多版本切换 http://www.linuxidc.com/Linux/2017-01/139325.htm

[翻译]Ubuntu 14.04, 13.10 下安装 OpenCV 2.4.9  http://www.linuxidc.com/Linux/2014-12/110045.htm

Ubuntu 安装 OpenCV 2.4.9  http://www.linuxidc.com/Linux/2016-12/138293.htm

Ubuntu 17.04下OpenCV源码编译安装  http://www.linuxidc.com/Linux/2017-10/147316.htm

OpenCV的详细介绍请点这里
OpenCV的下载地址请点这里

本文永久更新链接地址http://www.linuxidc.com/Linux/2017-11/148239.htm

linux
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款