Opencv line detection in an object

I have an image below. I want to define a line that divides this object into two parts. What is the best way? I tried with the Hough transform, but sometimes the object is not large enough to detect. Any ideas?

Thanks!

enter image description here

+8
opencv
source share
1 answer

Typically, the Hough transform is used to determine the line.

But if that doesn't work, a suitable line is also a good alternative.

The OpenCV fitline function opens for more information and options.

Since you've tried hough strings already, I will demonstrate an example string 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:

enter image description here

enter image description here

EDIT:

If you want to find a line for dividing an object into two parts, first find the fitting line, then find the line normal to it.

To do this, add the code snippet below the 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 that I got:

enter image description here

enter image description here

Hope this helps !!!

UPDATE:

Below is the C ++ code for the first Python code for your request. The code works fine for me. The output is the same as above:

 #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(); } 
+24
source share

All Articles