2016-01-06 9 views
0

Я хочу нарисовать Rect вокруг обнаруженных canny ребер. У меня есть это изображение, которое является результатом обнаружения глаз, морфологических операций и canny edge.Рисовать Прямо вокруг точки canny edge

enter image description here

Я попытался с помощью контуров обвил его по прямоугольнику, но результат был не точен.

Как я могу получить что-то вроде этого изображения?

required image result

Я использую эту функцию, чтобы нарисовать контуры:

void find_contour(Mat image) 
{ 
    Mat src_mat, gray_mat, canny_mat; 
    Mat contour_mat; 
    Mat bounding_mat; 

    contour_mat = image.clone(); 
    bounding_mat = image.clone(); 

    cvtColor(image, gray_mat, CV_GRAY2BGR); 

    // apply canny edge detection 

    Canny(gray_mat, canny_mat, 30, 128, 3, false); 

    //3. Find & process the contours 
    //3.1 find contours on the edge image. 

    vector< vector< cv::Point> > contours; 
    findContours(canny_mat, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); 

    //3.2 draw contours & property value on the source image. 

    int largest_area = 0; 
    int largest_contour_index = 0; 
    Rect bounding_rect; 

    for (size_t i = 0; i< contours.size(); i++) // iterate through each contour. 
    { 
     double area = contourArea(contours[i]); // Find the area of contour 

     if (area > largest_area) 
     { 
      largest_area = area; 
      largest_contour_index = i;    //Store the index of largest contour 
      bounding_rect = boundingRect(contours[i]); // Find the bounding rectangle for biggest contour 
     } 
    } 

    drawContours(image, contours, largest_contour_index, Scalar(0, 255, 0), 2); 

    imshow("Bounding ", image); 
} 
+0

ограничивающему прямоугольнику, созданный 'boundingRect()' "не точны"? Это правильно? Если вам нужна меньшая граница, вы можете попробовать 'cv :: minAreaRect()' для получения 'RotatedRect', который может быть меньше. Но ваш пример - это то, что вы получаете, если вы нарисуете 'bounding_rect', например. используя 'cv :: line()'. Не могли бы вы привести «неточный» пример и объяснить, где проблема? – Kellerspeicher

+0

Этот http://postimg.org/image/ursfkojs5/ выводит boundRect, используя контуры, он не рисует, как я хочу, на изображении выше – musta

+0

использовать 'cv :: rectangle (image, bounding_rect, cv :: Scalar (255,255,255))); 'перед имшоу. Но это будет делать только один (самый большой) ограничивающий прямоугольник контура, поэтому, если вы хотите ВСЕ, вам придется использовать вызов, который для каждого прямоугольника, а не только для самого большого контура. – Micka

ответ

1

в своем коде вы не рисовать прямоугольник вообще. Попробуйте это:

void find_contour(Mat image) 
{ 
Mat src_mat, gray_mat, canny_mat; 
Mat contour_mat; 
Mat bounding_mat; 

contour_mat = image.clone(); 
bounding_mat = image.clone(); 

cvtColor(image, gray_mat, CV_GRAY2BGR); 

// apply canny edge detection 

Canny(gray_mat, canny_mat, 30, 128, 3, false); 

//3. Find & process the contours 
//3.1 find contours on the edge image. 

vector< vector< cv::Point> > contours; 
findContours(canny_mat, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); 

//3.2 draw contours & property value on the source image. 

int largest_area = 0; 
int largest_contour_index = 0; 
Rect bounding_rect; 

for (size_t i = 0; i< contours.size(); i++) // iterate through each contour. 
{ 
    // draw rectangle around the contour: 
    cv::Rect boundingBox = boundingRect(contours[i]); 
    cv::rectangle(image, boundingBox, cv::Scalar(255,0,255)); // if you want read and "image" is color image, use cv::Scalar(0,0,255) instead 

    // you aren't using the largest contour at all? no need to compute it... 
    /* 
    double area = contourArea(contours[i]); // Find the area of contour 

    if (area > largest_area) 
    { 
     largest_area = area; 
     largest_contour_index = i;    //Store the index of largest contour 
     bounding_rect = boundingRect(contours[i]); // Find the bounding rectangle for biggest contour 
    } 
    */ 
} 

//drawContours(image, contours, largest_contour_index, Scalar(0, 255, 0), 2); 

imshow("Bounding ", image); 
} 
+0

HI @Micka спасибо за помощь, это результат все еще не точный http://postimg.org/image/4odd9xjix/ есть возможность Rect вокруг области глаз – musta

+0

выглядит как ваши контуры не так хороши? Если на самом деле этого достаточно, чтобы просто нарисовать самый большой контур (если вы хотите извлечь только самый большой контур), можете ли вы его нарисовать, адаптировав образец кода? – Micka

+0

Я обновил ваш код, но ничто не изменило тот же результат многих Rect вокруг области – musta

0

Вы можете сделать это так же,

findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); 
vector<RotatedRect> minRect(contours.size()); 

/// Draw contours 
Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3); 
for(int i = 0; i< contours.size(); i++) 
{ 
    Scalar color = Scalar(255, 255, 255); 
    cv::Rect boundingBox = cv::boundingRect(cv::Mat(contours[i])); 
    minRect[i] = minAreaRect(Mat(contours[i])); 
    drawContours(drawing, contours, i, color, 1, 8, hierarchy, 0, Point()); 
} 
for(int i = 0; i< contours.size(); i++) 
{ 
    // rotated rectangle 
    Point2f rect_points[4]; minRect[i].points(rect_points); 
    for(int j = 0; j < 4; j++) 
    line(drawing, rect_points[j], rect_points[(j+1)%4], Scalar(0,0,255), 1, 8); 
}