2014-12-08 3 views
1

Я пытаюсь извлечь вложенные изображения в этой imageOpenCV - Извлечение прямоугольники из образа

Binary Thresholding на 250 image

Контурыimage

Как вы можете видеть, это не префект, и он поднимает некоторые вещи, которые не имеют квадратной формы. Вот код:

Mat src; Mat src_gray; 
int thresh = 250; 
int max_thresh = 255; 
RNG rng(12345); 

/// Function header 
void thresh_callback(int, void*); 

/** @function main */ 
int main(int argc, char** argv) 
{ 
/// Load source image and convert it to gray 
src = imread("Media/RoadSignRecognitionUnknownSigns/RoadSignsComposite1.JPG", 1); 

/// Convert image to gray and blur it 
cvtColor(src, src_gray, CV_BGR2GRAY); 
blur(src_gray, src_gray, Size(3, 3)); 

/// Create Window 
char* source_window = "Source"; 
namedWindow(source_window, CV_WINDOW_AUTOSIZE); 
imshow(source_window, src); 

createTrackbar(" Threshold:", "Source", &thresh, max_thresh, thresh_callback); 
thresh_callback(0, 0); 

waitKey(0); 
return(0); 
} 

/** @function thresh_callback */ 
void thresh_callback(int, void*) 
{ 
Mat threshold_output; 
vector<vector<Point> > contours; 
vector<Vec4i> hierarchy; 

/// Detect edges using Threshold 
threshold(src_gray, threshold_output, thresh, 255, THRESH_BINARY); 
imshow("threshold_output", threshold_output); 
/// Find contours 
findContours(threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE,  Point(0, 0)); 

/// Approximate contours to polygons + get bounding rects and circles 
vector<vector<Point> > contours_poly(contours.size()); 
vector<Rect> boundRect(contours.size()); 
vector<Point2f>center(contours.size()); 
vector<float>radius(contours.size()); 

for (int i = 0; i < contours.size(); i++) 
{ 
    approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true); 
    boundRect[i] = boundingRect(Mat(contours_poly[i])); 
    minEnclosingCircle((Mat)contours_poly[i], center[i], radius[i]); 
} 


/// Draw polygonal contour + bonding rects + circles 
Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3); 
for (int i = 0; i< contours.size(); i++) 
{ 
    Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); 
    drawContours(drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point()); 
    rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0); 
    circle(drawing, center[i], (int)radius[i], color, 2, 8, 0); 
} 

/// Show in a window 
namedWindow("Contours", CV_WINDOW_AUTOSIZE); 
imshow("Contours", drawing); 
for (int i = 0; i < boundRect.size(); i++) 
{ 
    Mat patch = src(boundRect[i]); 
    //boundRect[i] 
    //Do whatever you want with the patch (imshow, imwrite,...) 
    imshow("Patch", patch); 
} 

for (int i = 0; i < boundRect.size(); i++){ 
    //int n = 1;// Here you will need to define n differently (for instance pick the largest  contour instead of the first one) 
    cv::Rect rect(boundRect[i]); 
    cv::Mat miniMat; 
    miniMat = src(rect); 
    imshow(""+to_string(i), miniMat); 
} 
} 

Как я могу сделать обнаружение формы лучше, пожалуйста?

+0

Вы пытаетесь обнаружить знак с этого изображения? или просто найти изображение, которое вы обрезали уже? –

+0

@BalajiR Да, это то, что я со временем буду делать. Поэтому я снимаю фотографии отдельно. –

ответ

1

Вот процедура для обнаружения Вход с изображения:

  1. Преобразование изображения в формат HSV. (0-10) & & (170-180).
  2. Dilate, Erode Binary Red Mask, чтобы найти границу.
  3. Найти контур с флагом RETR_EXTERNAL для извлечения только внешних контуров & Найдите ограничительную коробку этого контура.
  4. Фильтра Контур на основе известных свойств вывески, такие как круглые, треугольный, район, центр масс, моменты и т.д. ...
  5. Создать Войти Маску изображение Размер эквивалентна размером ограничивающего параллелепипеда & Нарисуйте Заполненный контур в маске.
  6. Установите ROI окна ввода в ограничительный прямоугольник Rect.
  7. Извлечь вывеску Выполните бит мудрый И вход с изображением знака.
  8. Изменение размера изображения до постоянной Размер позволяет говорить 100x100 & Выполнять сопоставление шаблонов/Любой другой алгоритм сопоставления. Также см. Эту демонстрационную демонстрацию для дальнейшей справки. https://sites.google.com/site/mcvibot2011sep/
1

Если ваши изображения не пересекаются, как в вашем примере, вы можете просто вычислить 2d ограничивающие поля для всех подключенных компонентов в вашем двоичном пороговом значении. Если они почти disjoint, то вы можете сделать эрозию в первую очередь.

+0

Спасибо, но как мне это сделать? –

+1

Чтобы вычислить связанные компоненты, вы берете граф, вершины которого являются черными пикселями, а ребра представляют собой пары соседних пикселей. Тогда каждый связный comp. на этом графике вы получите набор пикселей, и вы получите их ограничивающие поля, найдя их min/max x и y. – geoalgo

Смежные вопросы