【问题标题】:Turn image of lines into set of coordinates将线条图像转换为一组坐标
【发布时间】:2015-05-30 05:20:21
【问题描述】:

假设我有一张如上图所示的平面图。有没有简单的处理方法把这张图片变成一组坐标表示的线[(x1,y1),(x2,y2)],[(x2,y2),(x3,y3)],..., [(xn-1,yn-1),(xn,yn)]

【问题讨论】:

  • 这是您需要处理的图片代表,还是只是说明性草图?这会带来很大的不同。
  • 这是计算机视觉任务,在 CV 1 中没有这么简单的事情。你需要提供真实的输入图像,这样我们才能看到你真正在处理什么 2。我将从二值化图像开始通过一些阈值(但如果真实图像是不同的类型/噪声/照明,那么这可能不是方式) 3.通过霍夫变换或通过检查/回归找到的将直线连接在一起的相邻像素检测线此过程也称为矢量化所以你知道要寻找什么。如果线是轴/角度对齐的,或者恒定的已知宽度,这可以大大简化
  • 您的问题解决了吗?你还有什么问题吗?

标签: computer-vision polygon computational-geometry edge-detection


【解决方案1】:

我认为您想找到图像中所有线条的坐标。在 c++ 中按照简单的步骤很容易找到坐标:

  1. 阈值二进制反转
  2. 应用Thinning algorithm 减少厚度。
  3. 在二值图像中查找非零像素。
  4. 查找轮廓并应用近似多边形来近似点。

void thinningIteration(Mat& im, int iter)
{
    Mat marker = Mat::zeros(im.size(), CV_8UC1);
    for (int i = 1; i < im.rows-1; i++)
    {
        for (int j = 1; j < im.cols-1; j++)
        {
            uchar p2 = im.at<uchar>(i-1, j);
            uchar p3 = im.at<uchar>(i-1, j+1);
            uchar p4 = im.at<uchar>(i, j+1);
            uchar p5 = im.at<uchar>(i+1, j+1);
            uchar p6 = im.at<uchar>(i+1, j);
            uchar p7 = im.at<uchar>(i+1, j-1);
            uchar p8 = im.at<uchar>(i, j-1);
            uchar p9 = im.at<uchar>(i-1, j-1);

            int A  = (p2 == 0 && p3 == 1) + (p3 == 0 && p4 == 1) + 
                     (p4 == 0 && p5 == 1) + (p5 == 0 && p6 == 1) + 
                     (p6 == 0 && p7 == 1) + (p7 == 0 && p8 == 1) +
                     (p8 == 0 && p9 == 1) + (p9 == 0 && p2 == 1);
            int B  = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;
            int m1 = iter == 0 ? (p2 * p4 * p6) : (p2 * p4 * p8);
            int m2 = iter == 0 ? (p4 * p6 * p8) : (p2 * p6 * p8);

            if (A == 1 && (B >= 2 && B <= 6) && m1 == 0 && m2 == 0)
                marker.at<uchar>(i,j) = 1;
        }
    }
    im &= ~marker;
}

void thinning(Mat& im)
{
    im /= 255;
    Mat prev = Mat::zeros(im.size(), CV_8UC1);
    Mat diff;
    do 
    {
        thinningIteration(im, 0);
        thinningIteration(im, 1);
        absdiff(im, prev, diff);
        im.copyTo(prev);
    } 
    while (countNonZero(diff) > 0);

    im *= 255;
}

void main()
{
    Mat mSource_Bgr,mSource_Gray,mThreshold,mThinning;
    mSource_Bgr= imread(FileName_S.c_str(),IMREAD_COLOR);
    mSource_Gray= imread(FileName_S.c_str(),0);

    threshold(mSource_Gray,mThreshold,120,255,THRESH_BINARY_INV);

    mThinning= mThreshold.clone();

    thinning(mThinning);

    imshow("mThinning",mThinning);

    vector<Point2i> locations;   // output, locations of non-zero pixels 
    findNonZero(mThinning, locations);

    for (int i = 0; i < locations.size(); i++)
    {
        circle(mSource_Bgr,locations[i],2,Scalar(0,255,0),1);
    }

    imshow("mResult",mSource_Bgr);

    //To Find the Lines from the image
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    /// Find contours
    findContours( mThinning.clone(), contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
    /// Approximate contours to polygons + get bounding rects and circles
    vector<vector<Point> > contours_poly( contours.size() );
    for( size_t i = 0; i < contours.size(); i++ )
    { 
        approxPolyDP( Mat(contours[i]), contours_poly[i], 2, true );
    }

    for (int i = 0; i < contours_poly.size(); i++)
    {
        drawContours(mSource_Bgr,contours_poly,i,Scalar(255,0,0),2);
    }
    imshow("mResult",mSource_Bgr);

}

【讨论】:

  • 只返回他需要的多边形矢量形式的图像......你也忘记指定你的代码是用什么语言编写的(或者我错过了)
  • 感谢@Spektre 指出我的误解。现在我想事情是有道理的!
猜你喜欢
  • 2013-09-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-22
  • 2015-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多