2017-02-18 10 views
2

Я хочу, чтобы обнаружить красные и зеленые круги отдельно в следующем изображении (и несколько других подобных изображений)Detect красный и зеленый круги

image

Я использую OpenCV и питона.

Я пробовал использовать houghcircles, но это не помогло даже после смены параметров.

Любое предложение, как это сделать, действительно поможет. Буду признателен, если кто-то отправит код

+0

Простой цвет Сегментация даст хорошие результаты в этом случае. – ZdaR

+0

Возможный дубликат [python opencv - обнаружение blob или обнаружение круга] (http://stackoverflow.com/questions/42203898/python-opencv-blob-detection-or-circle-detection) – mdegis

+0

Размер кругов всегда одинаковый (внутри и между изображениями)? Цвет внутри круга постоянный? – Micka

ответ

7

Вы упомянули в комментариях, что круги всегда будут иметь одинаковый размер. Давайте воспользуемся этим фактом. Мои фрагменты кода находятся на языке C++, но это не должно быть проблемой, потому что они предназначены только для того, чтобы показать, какие функции OpenCV использовать (и как) ...

TL; DR Сделайте это:

  1. Создать типичное изображение круга - изображение шаблона.
  2. Используйте template matching, чтобы получить все положения круга.
  3. Проверьте цвет каждого круга.

Теперь давайте начнем!

Шаг 1 - Шаблон изображения

Вам нужно изображение, которое показывает круг, который четко отделен от фона. У вас есть два варианта (оба одинаково хороши):

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

Круг может быть любого цвета - важно только, чтобы он отличался от фона.

enter image description here

Шаг 2 - Шаблон соответствия

Загрузите изображение и шаблон изображения и преобразовывать их в HSV color space. Затем разделить каналы так, что вы будете иметь возможность работать только с насыщения канала:

using namespace std; 
using namespace cv; 

Mat im_rgb = imread("circles.jpg"); 
Mat tm_rgb = imread("template.jpg"); 

Mat im_hsv, tm_hsv; 
cvtColor(im_rgb, im_hsv, CV_RGB2HSV); 
cvtColor(tm_rgb, tm_hsv, CV_RGB2HSV); 
vector<Mat> im_channels, tm_channels; 
split(im_hsv, im_channels); 
split(tm_hsv, tm_channels); 

Вот как круги и шаблон посмотри:

enter image description hereenter image description here

Далее, вы должны получить изображение который будет содержать информацию о граница круга.Независимо от того, что вы делаете для достижения этого, вы должны применить точно такие же операции на каналах насыщения изображения и шаблона. Я использовал оператора sobel, чтобы выполнить работу. Пример кода показывает только те операции, которые я сделал на канале насыщения изображения; канал насыщения шаблон прошел точно такой же методике:

Mat im_f; 
im_channels[1].convertTo(im_f, CV_32FC1); 
GaussianBlur(im_f, im_f, Size(3, 3), 1, 1); 
Mat sx, sy; 
Sobel(im_f, sx, -1, 1, 0); 
Sobel(im_f, sy, -1, 0, 1); 

Mat image_input = abs(sx) + abs(sy); 

Вот как круги на полученном изображении и шаблон выглядит следующим образом: enter image description hereenter image description here

Теперь выполнить согласование шаблона. Я советую вам выбрать тип соответствия шаблона, который вычисляет нормированные коэффициенты корреляции:

Mat match_result; 
matchTemplate(image_input, template_input, match_result, CV_TM_CCOEFF_NORMED); 

Это результат соответствующий шаблон:

enter image description here

Этот образ говорит вам, насколько хорошо шаблон соотносится с если вы поместите шаблон в разные позиции на изображении. Например, значение результата в пикселе (0,0) соответствует шаблону, помещенному на (0,0) на входном изображении.

Когда шаблон размещен в таком положении, что он хорошо совпадает с основным изображением, коэффициент корреляции является высоким. Используйте пороговый метод, чтобы сбросить все, кроме пиков сигнала (значения согласования шаблона будет лежать внутри [-1, 1] интервал, и вы заинтересованы только в значениях, близких к 1):

Mat thresholded; 
threshold(match_result, thresholded, 0.8, 1.0, CV_THRESH_BINARY); 

enter image description here

Затем определите положения максимумов результата шаблона внутри каждой изолированной области. Я рекомендую вам использовать пороговое изображение в качестве маски для этой цели. В каждой области необходимо выбрать только один максимум.

Эти положения говорят вам, где вы должны разместить шаблон, чтобы он соответствовал лучшим с кругами. Я обратил прямоугольники, которые начинаются в этих точках и имеют одинаковую ширину/высоту, как шаблон изображение:

enter image description here

Шаг 3: цвет круга

Теперь вы знаете, где шаблоны должны быть расположены так что они красиво покрывают круги. Но вам все равно нужно выяснить, где находится центр круга на образце шаблона. Вы можете сделать это путем вычисления центра масс насыщения канала шаблона:

enter image description here

На изображении, круг центры расположены в этих точках:

Point circ_center_on_image = template_position + circ_center_on_template; 

Теперь у вас есть только проверить если интенсивность красного цвета в этих точках больше, чем интенсивность зеленого канала. Если да, то круг красного цвета, в противном случае это зеленый:

enter image description here

+0

Спасибо Necj. Это помогло – StupidGuy