2012-10-31 5 views
5

खैर सवाल यह सब कहते हैं लाइन नहीं,कैसे लाइन आकर्षित करने के लिए खंड OpenCV 2.4.2

मैं समारोह Line() है, जो दो बिंदुओं के बीच रेखा खंड खींचता है पता है।

मैं, लाइन नहीं एक रेखा खंड आकर्षित करने के लिए भी लाइन खंड के दो अंक का उपयोग कर की जरूरत है।


[एन: क्या पहले से प्रश्न के लिए एक जवाब के रूप में पोस्ट किया गया से संपादित करें]

मैं अपने समाधान का इस्तेमाल किया और यह क्षैतिज लाइनों में अच्छे परिणाम प्रदर्शन किया, लेकिन मैं अभी भी खड़ी लाइनों में समस्याओं मिला ।

उदाहरण के लिए, 600x600 पिक्सल वाली छवि पर बिंदु [306,411] और [304,8] (बैंगनी) और ड्रॉ लाइन (लाल) का उपयोग करके एक उदाहरण के नीचे निम्नानुसार है। क्या आपके पास कुछ टिप है?

enter image description here

उत्तर

6

आप ऐसा करने के लिए है कि खुद के लिए एक समारोह लिखने के लिए की आवश्यकता होगी। मेरा सुझाव है कि आप अपनी लाइन को कुल्हाड़ी + + = 0 फॉर्म में डाल दें और फिर इसे अपनी छवि के 4 किनारों से अलग करें। याद रखें कि क्या आपके पास फॉर्म में एक पंक्ति है [बी बी] एक और रेखा के साथ अपने चौराहे को ढूंढना केवल दोनों का क्रॉस उत्पाद है। अपनी छवि के किनारों

top_horizontal = [0 1 0]; 
left_vertical = [1 0 0]; 
bottom_horizontal = [0 1 -image.rows]; 
right_vertical = [1 0 -image.cols]; 

भी हो सकता है, अगर आप अपने बिंदुओं के बीच दूरी आप भी प्रत्येक दिशा में रेखा के साथ बहुत दूर अंक ले सकता है के बारे में कुछ पता है, मैं अंक को सौंप दिया नहीं लगता कि रेखा() छवि पर होना चाहिए।

5

मुझे लगता है कि यह बहुत पुराना सवाल है। मैं वास्तव में एक ही समस्या थी और मैं इस सरल कोड का इस्तेमाल किया:

double Slope(int x0, int y0, int x1, int y1){ 
    return (double)(y1-y0)/(x1-x0); 
} 

void fullLine(cv::Mat *img, cv::Point a, cv::Point b, cv::Scalar color){ 
    double slope = Slope(a.x, a.y, b.x, b.y); 

    Point p(0,0), q(img->cols,img->rows); 

    p.y = -(a.x - p.x) * slope + a.y; 
    q.y = -(b.x - q.x) * slope + b.y; 

    line(*img,p,q,color,1,8,0); 
} 

सबसे पहले मैं रेखा खंड की एक ढलान की गणना और फिर मैं "विस्तार" छवि की सीमाओं में रेखा खंड। मैं लाइन के नए बिंदुओं की गणना करता हूं जो x = 0 और x = image.width में स्थित हैं। बिंदु स्वयं छवि के बाहर हो सकता है, जो कि एक तरह का बुरा चाल है, लेकिन समाधान बहुत आसान है।

+1

यह ओपनसीवी के लिए सही जवाब है। चयनित उत्तर बकवास है। मैंने इसकी प्रतिलिपि बनाई और चिपकाया और यह काम करता है। बहुत बहुत धन्यवाद। –

+1

क्रैश होगा यदि x1-x0 = 0. –

1

यह उत्तर pajus_cz उत्तर से फोर्क किया गया है लेकिन थोड़ा सुधार हुआ है।

हमारे पास दो अंक हैं और हमें सीधी रेखा खींचने में सक्षम होने के लिए लाइन समीकरण y = mx + b प्राप्त करने की आवश्यकता है।

हम

1- ढाल (एम)

Slope equation

2- जो लाइन समीकरण के माध्यम से प्राप्त किया जा सकता है किसी भी बिन्दु का उपयोग कर प्राप्त करने की आवश्यकता दो चर रहे हैं दोनों से हम ढलान की ढलान की गणना के बाद ही हैं।

void drawStraightLine(cv::Mat *img, cv::Point2f p1, cv::Point2f p2, cv::Scalar color) 
{ 
     Point2f p, q; 
     // Check if the line is a vertical line because vertical lines don't have slope 
     if (p1.x != p2.x) 
     { 
       p.x = 0; 
       q.x = img->cols; 
       // Slope equation (y1 - y2)/(x1 - x2) 
       float m = (p1.y - p2.y)/(p1.x - p2.x); 
       // Line equation: y = mx + b 
       float b = p1.y - (m * p1.x); 
       p.y = m * p.x + b; 
       q.y = m * q.x + b; 
     } 
     else 
     { 
       p.x = q.x = p2.x; 
       p.y = 0; 
       q.y = img->rows; 
     } 

     cv::line(*img, p, q, color, 1); 
} 
3

मैं एक ही समस्या थी और पता चला कि इसमें 2.4.X OpenCV पर एक known bug है, नए संस्करण के लिए पहले से ही तय की।

2.4.X संस्करणों के लिए, समाधान साजिश से पहले लाइन में प्रयोग क्लिप है cv::clipLine()

यहां एक समारोह मैं अपने आप से किया था कि 2.4.13 OpenCV पर ठीक काम करता है है

void Detector::drawFullImageLine(cv::Mat& img, const std::pair<cv::Point, cv::Point>& points, cv::Scalar color) 
{ 
    //points of line segment 
    cv::Point p1 = points.first; 
    cv::Point p2 = points.second; 

    //points of line segment which extend the segment P1-P2 to 
    //the image borders. 
    cv::Point p,q; 

    //test if line is vertical, otherwise computes line equation 
    //y = ax + b 
    if (p2.x == p1.x) 
    { 
     p = cv::Point(p1.x, 0); 
     q = cv::Point(p1.x, img.rows); 
    } 
    else 
    { 
     double a = (double)(p2.y - p1.y)/(double) (p2.x - p1.x); 
     double b = p1.y - a*p1.x; 

     p = cv::Point(0, b); 
     q = cv::Point(img.rows, a*img.rows + b); 

     //clipline to the image borders. It prevents a known bug on OpenCV 
     //versions 2.4.X when drawing 
     cv::clipLine(cv::Size(img.rows, img.cols), p, q); 
    } 

    cv::line(img, p, q, color, 2); 
} 
+0

'cv :: clipLine()' OpenCV के लिए सही समाधान है। यह जवाब स्वीकार किया जाना चाहिए। बहुत बहुत धन्यवाद – Arxeiss

संबंधित मुद्दे