2013-01-06 66 views
8

Tôi có hình ảnh bên dưới. Tôi muốn phát hiện đường phân chia đối tượng này thành hai phần. Đó là cách tốt nhất? Tôi đã thử với biến đổi Hough nhưng đôi khi đối tượng không đủ lớn để nó phát hiện. Bất kỳ ideias?Phát hiện các dòng Opencv trong đối tượng

Cảm ơn!

enter image description here

Trả lời

24

Thông thường, Hough transform được sử dụng để phát hiện dòng.

Nhưng nếu nó không hoạt động cho bạn, đường phù hợp cũng là một lựa chọn tốt.

Kiểm tra OpenCV fitline chức năng để biết thêm chi tiết và thông số.

Vì bạn đã thử dòng hough, tôi sẽ chứng minh dòng phù hợp ở đây, sử dụng 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() 

Dưới đây là kết quả tôi nhận:

enter image description here

enter image description here

CHỈNH SỬA:

Nếu bạn muốn tìm dòng để chia đối tượng thành hai phần, trước tiên hãy tìm đường phù hợp, sau đó tìm dòng bình thường với nó.

Cho rằng, thêm bên dưới đoạn mã dưới cv2.fitLine() chức năng:

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

Và dưới đây là những kết quả tôi nhận:

enter image description here

enter image description here

Hope nó giúp !!!

UPDATE:

Dưới đây là C++ mã cho Python mã của trường hợp đầu tiên như bạn yêu cầu. Mã hoạt động tốt cho tôi. Đầu ra là giống như đưa ra ở trên:

#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(); 
} 
+1

Cảm ơn bạn rất nhiều, tôi sẽ cố gắng ngày hôm nay: D Ồ, tôi là một fan hâm mộ của blog của bạn :) –

+0

Bạn có bất cứ phiên bản dành cho C++? : P –

+1

Xin chào, tất cả các chức năng đều là các chức năng tiêu chuẩn từ OpenCV. Vì vậy, nếu bạn kiểm tra các tài liệu opencv, bạn có thể tìm thấy các hàm C++ tương ứng cho mọi hàm python mà tôi đã sử dụng. Hãy thử nó cho mình, và nếu bạn tìm thấy bất kỳ khó khăn, bình luận cho tôi. Tôi sẽ cố gắng giúp đỡ ... –

Các vấn đề liên quan