Detect Lines Opencv in object

前端 未结 1 2049
我在风中等你
我在风中等你 2020-12-13 07:40

I have the image below. I want to detect the line that divides this object in two pieces. Which is the best way? I\'ve tried with the Hough transform but sometimes the objec

1条回答
  •  执笔经年
    2020-12-13 08:23

    Normally, Hough Transform is used for line detection.

    But if it doesn't work for you, fitting line is also a good alternative.

    Check OpenCV fitline function for more details and parameters.

    Since you have already tried hough lines, I will demonstrate fitting line here, using 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()
    

    Below is the result I got :

    enter image description here

    enter image description here

    EDIT :

    If you want to find the line to divide the object into two pieces, first find the fitting line, then find the line normal to it.

    For that, add below piece of code under cv2.fitLine() function :

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

    And below are the results I got :

    enter image description here

    enter image description here

    Hope it helps !!!

    UPDATE :

    Below is the C++ code for Python code of first case as you requested. The code works fine for me. Output is same as given above :

    #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    using namespace cv;
    
    int main()
    {
        cv::Mat img, gray,thresh;
        vector> 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();
    }
    

    0 讨论(0)
提交回复
热议问题