2016-01-09 2 views
1

В настоящее время я пытаюсь использовать функцию сопоставления шаблонов OpenCV для обнаружения всех похожих объектов в данном изображении с использованием шаблона. Тем не менее, я не получаю все объекты (которые являются клетками крови), которые будут обнаружены, хотя они в значительной степени похожи и идентичны. Я искал в Интернете решение, но не получил.Шаблон соответствия OpenCV Подобный объект

Ниже мой код:

cv::Mat ref = cv::imread("c:\\image.jpg"); 
cv::Mat tpl = cv::imread("c:\\template.jpg"); 

cv::Mat gref, gtpl; 
cv::cvtColor(ref, gref, CV_BGR2GRAY); 
cv::cvtColor(tpl, gtpl, CV_BGR2GRAY); 

cv::Mat res(ref.rows-tpl.rows+1, ref.cols-tpl.cols+1, CV_32FC1); 
cv::matchTemplate(gref, gtpl, res, CV_TM_CCOEFF_NORMED); 
cv::threshold(res, res, 0.8, 1., CV_THRESH_TOZERO); 

while (true) 
{ 
    double minval, maxval, threshold = 0.8; 
    cv::Point minloc, maxloc; 
    cv::minMaxLoc(res, &minval, &maxval, &minloc, &maxloc); 

    if (maxval >= threshold) 
    { 
     cv::rectangle(
      ref, 
      maxloc, 
      cv::Point(maxloc.x + tpl.cols, maxloc.y + tpl.rows), 
      CV_RGB(0,255,0), 2 
     ); 
     cv::floodFill(res, maxloc, cv::Scalar(0), 0, cv::Scalar(.1), cv::Scalar(1.)); 
    } 
    else 
     break; 
} 

cv::imshow("reference", ref); 

Это результат и изображение, используемое:

Учитывая Изображение

Given Image

Шаблон

Template

Результат с более высокой настройки порогового значения (0,8/0,8)

Result

Результат с более низкими параметрами пороговых (0,6/0,3)

enter image description here

Я довольно новыми для согласования шаблона является существует ли способ обнаружения всех объектов в изображении?

Мне нужен шаблон для обнаружения ячеек в еще более сложном изображении.

enter image description here

+1

Изменить пороговое значение? – nbsrujan

+0

Я попытался понизить порог, но все еще не обнаружил все объекты – Woody

+0

Можете ли вы загрузить изображение res image – nbsrujan

ответ

2

В вашем конкретном случае вам не нужно использовать согласование шаблона. Вместо этого вы можете использовать только красный компонент для обнаружения капли. Если вы используете OpenCV 3.0+, вы можете использовать cv::SimpleBlobDetector.

В любом случае, вы можете использовать простой детектор, используя cv::threshold и cv::findContours. Я попытался следующий код:

int main() 
{ 
    const int threshVal = 30; 
    const int minArea = 15 * 15; 
    const int maxArea = 100 * 100; 
    cv::Mat img = cv::imread("input.jpg"); 

    cv::Mat bgr[3]; 
    cv::split(img, bgr); 

    cv::Mat red_img = bgr[2]; 
    cv::threshold(red_img, red_img, threshVal, 255, cv::THRESH_BINARY); 

    vector<vector<Point>> contours; 
    vector<Vec4i> hierarchy; 
    cv::findContours(red_img, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); 

    for (int i = 0; i < contours.size(); i++) 
    { 
    int area = cv::contourArea(contours[i]); 
    if (area < minArea || area > maxArea) 
     continue; 

    cv::Rect roi = cv::boundingRect(contours[i]); 
    cv::rectangle(img, roi, cv::Scalar(0, 255, 0), 2); 
    } 

    cv::imshow("result", img); 
    cv::waitKey(0); 
    return 0; 
} 

И этот код определяет все клетки крови:

enter image description here

Конечно, вам может потребоваться настроить значения трех констант (threshVal, minArea, maxArea), чтобы получить лучшие результаты по всем вашим образцам.

+0

Извините за задержку, я использовал этот метод раньше, но он не очень хорошо работает в этом виде изображения [link] (http://i.imgur.com/D0cHxkV.jpg). Большинство ячеек, которые упакованы вместе, считаются только 1 ячейкой – Woody

+0

@Woody По этой точной причине у вас есть параметры minArea и maxArea. –

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