2016-06-20 120 views
0

我正在使用OpenCV和Python。我試圖畫出輪廓內最長的線。在輪廓中繪製最長的線OPENCV

我有一個名爲cnt的輪廓。圖像是二元的,輪廓內部是白色的,外部是黑色的。我想畫出白色輪廓內最長的線條。我發現如何使用cv2.lines畫線,但我沒有找到如何繪製最長的線。你有什麼想法?

img_copy = cv2.dilate(copy.deepcopy(img), np.ones((2,2),np.uint8),iterations = 2) 
contours, hierarchy = cv2.findContours(copy.deepcopy(img_copy),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) 
areas = [cv2.contourArea(c) for c in contours] 
max_index = np.argmax(areas) 
cnt = contours[max_index] 
+0

請您所需的輸出添加一些樣本圖像! –

+0

它不依賴於圖像,我將尋找一種方法來查找輪廓中的所有直線,然後選擇最長的一條。 – Hazel

+0

嘗試HoughLines algorthim找到它。 –

回答

0

以下方法用於從圖像中繪製行數並獲取最大值的程度嘗試此操作。它的做工精細

Mat Compute_skewAngle (Mat& src,Mat& src_gray,int drawLine) { 

int thresh = 100; 
RNG rng(12345); 


// 1. Load Gray Scae Image 
// 2. Get Size of Image 
cv::Size size = src_gray.size(); 
// 3. blur the Grayscale image 
cv::blur(src_gray, src_gray, cv::Size(3,3)); 



cv::Mat threshold_output; 
std::vector<std::vector<cv::Point> > contours; 
std::vector<Vec4i> hierarchy; 


// 4. Detect edges using Threshold/Canny edge Detector 
//cv::threshold(src_gray, threshold_output, thresh, 255, THRESH_BINARY); 
Mat dst, cdst; 
cv::Canny(src_gray, dst, thresh, 200, 3); 

// 5. Gray Image to BGR 
cvtColor(dst, cdst, CV_GRAY2BGR); 


#if 0 
vector<Vec2f> lines; 
HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0); 

for(size_t i = 0; i < lines.size(); i++) 
{ 
    float rho = lines[i][0], theta = lines[i][1]; 
    Point pt1, pt2; 
    double a = cos(theta), b = sin(theta); 
    double x0 = a*rho, y0 = b*rho; 
    pt1.x = cvRound(x0 + 1000*(-b)); 
    pt1.y = cvRound(y0 + 1000*(a)); 
    pt2.x = cvRound(x0 - 1000*(-b)); 
    pt2.y = cvRound(y0 - 1000*(a)); 
    line(cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA); 
} 
#else 
vector<Vec4i> lines; 

double angle = 0.; 
int countNegative = 0; 
int countPositive =0; 

HoughLinesP(dst, lines, 1, CV_PI/180, 100, 10, 100); 

NSMutableDictionary *angleCountDict = [[NSMutableDictionary alloc] init]; 

for(size_t i = 0; i < lines.size(); i++) 
{ 
    if(drawLine == 1) { // draw line while pass flag value 1 
     Vec4i l = lines[i]; 
     line(cdst, cv::Point(l[0], l[1]), cv::Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA); 
    } 


    double delta_y = lines[i][3] - lines[i][1]; 
    double delta_x = lines[i][2] - lines[i][0]; 
    double currentAngle =atan2(delta_y,delta_x); 
    int angleAsDeg = abs(currentAngle * 180/CV_PI); 


    NSString *_retValue = [angleCountDict objectForKey:[NSString stringWithFormat:@"%d", angleAsDeg]]; 
    int angleCount = [_retValue intValue]; 
    [angleCountDict setObject:[NSNumber numberWithInt:angleCount + 1] forKey:[NSString stringWithFormat:@"%d", angleAsDeg]]; 

    double slope = delta_y/delta_x ; // find the slope to detect the angle " - " or " + " 
    if(slope < 0) 
     countNegative ++; 
    else 
     countPositive ++; 
} 

#endif 

// sort the dictionary to get the largest value of degree count 
NSArray *blockSortedKeys = [angleCountDict keysSortedByValueUsingComparator: ^(id obj1, id obj2) { 
    return [obj2 compare:obj1]; 
}]; 


NSString *degreeVal; 
if([blockSortedKeys count] > 0) 
    degreeVal = [blockSortedKeys objectAtIndex:0]; 


angle = [degreeVal doubleValue]; 

if(countNegative > countPositive) { 
    angle = - angle; 
} 
Mat outPut; 
outPut = rotateMatImage(src,angle,cdst); 

return outPut; 

}