如何在open cv c ++

时间:2017-02-17 17:21:42

标签: c++ windows opencv

我正在使用以下代码使用c ++在open cv 3中对以下图像进行框架化。输入图像如下。 enter image description here

#include "stdafx.h"
#include <opencv2/opencv.hpp>

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv/cvaux.h>
#include <opencv2/core/core.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/highgui/highgui.hpp>


using namespace cv;
using namespace std;

/**
* Perform one thinning iteration.
* Normally you wouldn't call this function directly from your code.
*
* Parameters:
*       im    Binary image with range = [0,1]
*       iter  0=even, 1=odd
*/
void thinningIteration(cv::Mat& img, int iter)
{
    CV_Assert(img.channels() == 1);
    CV_Assert(img.depth() != sizeof(uchar));
    CV_Assert(img.rows > 3 && img.cols > 3);

    cv::Mat marker = cv::Mat::zeros(img.size(), CV_8UC1);

    int nRows = img.rows;
    int nCols = img.cols;

    if (img.isContinuous()) {
        nCols *= nRows;
        nRows = 1;
    }

    int x, y;
    uchar *pAbove;
    uchar *pCurr;
    uchar *pBelow;
    uchar *nw, *no, *ne;    // north (pAbove)
    uchar *we, *me, *ea;
    uchar *sw, *so, *se;    // south (pBelow)

    uchar *pDst;

    // initialize row pointers
    pAbove = NULL;
    pCurr = img.ptr<uchar>(0);
    pBelow = img.ptr<uchar>(1);

    for (y = 1; y < img.rows - 1; ++y) {
        // shift the rows up by one
        pAbove = pCurr;
        pCurr = pBelow;
        pBelow = img.ptr<uchar>(y + 1);

        pDst = marker.ptr<uchar>(y);

        // initialize col pointers
        no = &(pAbove[0]);
        ne = &(pAbove[1]);
        me = &(pCurr[0]);
        ea = &(pCurr[1]);
        so = &(pBelow[0]);
        se = &(pBelow[1]);

        for (x = 1; x < img.cols - 1; ++x) {
            // shift col pointers left by one (scan left to right)
            nw = no;
            no = ne;
            ne = &(pAbove[x + 1]);
            we = me;
            me = ea;
            ea = &(pCurr[x + 1]);
            sw = so;
            so = se;
            se = &(pBelow[x + 1]);

            int A = (*no == 0 && *ne == 1) + (*ne == 0 && *ea == 1) +
                (*ea == 0 && *se == 1) + (*se == 0 && *so == 1) +
                (*so == 0 && *sw == 1) + (*sw == 0 && *we == 1) +
                (*we == 0 && *nw == 1) + (*nw == 0 && *no == 1);
            int B = *no + *ne + *ea + *se + *so + *sw + *we + *nw;
            int m1 = iter == 0 ? (*no * *ea * *so) : (*no * *ea * *we);
            int m2 = iter == 0 ? (*ea * *so * *we) : (*no * *so * *we);

            if (A == 1 && (B >= 2 && B <= 6) && m1 == 0 && m2 == 0)
                pDst[x] = 1;
        }
    }

    img &= ~marker;
}

/**
* Function for thinning the given binary image
*
* Parameters:
*       src  The source image, binary with range = [0,255]
*       dst  The destination image
*/
void thinning(const cv::Mat& src, cv::Mat& dst)
{
    dst = src.clone();
    dst /= 255;         // convert to binary image

    cv::Mat prev = cv::Mat::zeros(dst.size(), CV_8UC1);
    cv::Mat diff;

    do {
        thinningIteration(dst, 0);
        thinningIteration(dst, 1);
        cv::absdiff(dst, prev, diff);
        dst.copyTo(prev);
    } while (cv::countNonZero(diff) > 0);

    dst *= 255;
}



/**
* This is an example on how to call the thinning funciton above
*/





int main()
{
    cv::Mat src = cv::imread("G:\\realimage9.jpg");
    /*Mat image = imread("G:\\realimage.jpg", CV_LOAD_IMAGE_UNCHANGED);*/
    if (!src.data)
        return -1;


    cv::Mat bw;
    cv::cvtColor(src, bw, CV_BGR2GRAY);







    //  /*dilate(bw, bw, Mat(), Point(-1, -1), 4);
    //  erode(bw, bw, Mat(), Point(-1, -1), 2);*/
    GaussianBlur(bw, bw, cv::Size(9, 9), 2, 2);

    cv::imshow("blur", bw);

    cv::threshold(bw, bw, 10, 255, CV_THRESH_BINARY_INV);
    cv::imshow("convert", bw);




    thinning(bw, bw);
    cv::imshow("src", src);
    cv::imshow("dst", bw);
    cv::waitKey();
    return 0;



}

我得到的输出是enter image description here

这不够顺利。我在这里使用了zhang-suen-thinning算法。我从互联网上得到了这个代码。我是新手,打开cv和C ++。我被困在这里。我的下一步是提取端点,孔等功能。因此,有些人可以帮助我获得更好的平滑骨架图像。

1 个答案:

答案 0 :(得分:3)

这是一个悬而未决的问题。

这是一篇论文加上一个在网络上运行的java程序,可以或多或少地执行你想要的程序。但它应该被认为是实验性的。

enter image description here

如果您发现this code对您的研究/软件有用,请考虑引用以下出版物:

  

AndrésSolísMontero和Jochen Lang。 Skeleton pruning by contour approximation and the integer medial axis transform。   计算机与计算机图形,Elsevier,2012。

贡献者
  1. Andrés Solís Montero
  2. Jochen Lang
  3. David Lareau
  4. Ana Laura Perez
  5. Corey Edmunds