【问题标题】:Detect Lines Opencv in object检测对象中的线条 Opencv
【发布时间】:2017-11-14 03:35:53
【问题描述】:

我有下面的图片。我想检测将这个对象分成两部分的线。哪个是最好的方法?我已经尝试过霍夫变换,但有时对象不够大,无法检测到。有什么想法吗?

谢谢!

【问题讨论】:

    标签: opencv


    【解决方案1】:

    通常,霍夫变换用于线检测。

    但如果它不适合你,拟合线也是一个不错的选择。

    查看 OpenCV fitline 函数了解更多详细信息和参数。

    由于你已经尝试过霍夫线,我将在这里演示拟合线,使用 OpenCV-Python :

    # Load image, convert to grayscale, threshold and find contours
    img = cv2.imread('lail.png')
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
    contours,hier = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
    cnt = contours[0]
    
    # then apply fitline() function
    [vx,vy,x,y] = cv2.fitLine(cnt,cv2.cv.CV_DIST_L2,0,0.01,0.01)
    
    # Now find two extreme points on the line to draw line
    lefty = int((-x*vy/vx) + y)
    righty = int(((gray.shape[1]-x)*vy/vx)+y)
    
    #Finally draw the line
    cv2.line(img,(gray.shape[1]-1,righty),(0,lefty),255,2)
    cv2.imshow('img',img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    下面是我得到的结果:

    编辑:

    如果你想找到将物体分成两部分的线,首先找到拟合线,然后找到垂直于它的线。

    为此,在 cv2.fitLine() 函数下添加以下代码:

    nx,ny = 1,-vx/vy
    mag = np.sqrt((1+ny**2))
    vx,vy = nx/mag,ny/mag
    

    以下是我得到的结果:

    希望对你有帮助!!!

    更新:

    以下是您要求的第一种情况下的 Python 代码的 C++ 代码。该代码对我来说很好。输出与上面给出的相同:

    #include <iostream>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/core/core.hpp>
    #include <opencv/cv.h>
    
    using namespace std;
    using namespace cv;
    
    int main()
    {
        cv::Mat img, gray,thresh;
        vector<vector<Point>> contours;
        Vec4f lines;
    
        img = cv::imread("line.png");
        cv::cvtColor(img,gray,cv::COLOR_BGR2GRAY);
        cv::threshold(gray,thresh,127,255,cv::THRESH_BINARY);
        cv::findContours(thresh,contours,cv::RETR_LIST,cv::CHAIN_APPROX_SIMPLE);
        cv::fitLine(Mat(contours[0]),lines,2,0,0.01,0.01);
    
        //lefty = int((-x*vy/vx) + y)
        //righty = int(((gray.shape[1]-x)*vy/vx)+y)
        int lefty = (-lines[2]*lines[1]/lines[0])+lines[3];
        int righty = ((gray.cols-lines[2])*lines[1]/lines[0])+lines[3];
    
        cv::line(img,Point(gray.cols-1,righty),Point(0,lefty),Scalar(255,0,0),2);
    
        cv::imshow("img",img);
        cv::waitKey(0);
        cv::destroyAllWindows();
    }
    

    【讨论】:

    • 非常感谢,我今天会试试这个 :D 哦,我是你博客的粉丝 :)
    • 你有 C++ 的版本吗? :P
    • 您好,所有函数都是OpenCV的标准函数。因此,如果您查看 opencv 文档,您可以为我使用的每个 python 函数找到相应的 C++ 函数。请自己尝试,如果您发现任何困难,请评论我。我会尽力帮助...
    • +1 - 谢谢,很高兴知道您从我的博客中受益。继续访问,如果您愿意,可以分享。
    • 抱歉这么久。我做到了,谢谢 :) 检查我的最新项目:youtube.com/watch?v=zXHXusO8eGw
    猜你喜欢
    • 2018-01-01
    • 1970-01-01
    • 2018-10-21
    • 1970-01-01
    • 2021-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多