2013-01-06 63 views
8

我有下圖。我想要檢測將這個對象分成兩部分的線。哪種方法最好?我已經嘗試過霍夫變換,但有時物體不夠大,無法檢測到。任何意識?檢測物體中的線Opencv

謝謝!

enter image description here

回答

24

通常,Hough變換用於線檢測。

但是,如果它不適合你,擬合線也是一個很好的選擇。

檢查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() 

下面是我得到的結果是:

enter image description here

enter image description here

編輯:

如果您想查找將物體分成兩部分的線,請首先找到擬合線,然後找到與其垂直的線。

對於這一點,下面添加一段代碼cv2.fitLine下()函數:

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

並在下文中我得到的結果:

enter image description here

enter image description here

希望它有助於 !!!

UPDATE:

下面是你請求的第一案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(); 
} 
+1

非常感謝你,我會嘗試這個今天:d 哦,我是你的博客的粉絲:) –

+0

你有C++的任何版本的? :P –

+1

嗨,所有的功能都是OpenCV的標準功能。因此,如果您檢查opencv文檔,您可以爲我使用的每個python函數找到相應的C++函數。請自己嘗試,如果您發現任何困難,請評論我。我會盡力幫助... –