Обнаружение полных, полных кругов с OpenCV

У меня есть изображение, на котором показаны два круга с одним и тем же центром, но с разным радиусом - внутренний и внешний круг. Мне нужно проверить, если эти два круга "сломаны", это означает, что форма кругов как-то потрепана или потрепана.

Круги всегда имеют одинаковый радиус, поэтому я использую HoughCircles OpenCV с заданным радиусом для каждого из двух кругов, чтобы определить, содержит ли изображение эти два круга. Круги можно найти без проблем. У меня довольно мало опыта в обработке изображений, поэтому я подумал, что использование HoughCircles найдет круги только в том случае, если их форма безупречна, но HoughCircles также находит круги, если они являются ребрами или кривыми на обводке круга.

Есть ли лучший способ проверить, целы ли два круга или HoughCircles совершенно неправильный? Я немного поигрался с пороговыми параметрами HoughCircles, но когда порог установлен слишком низко, алгоритм вообще не находит круг, независимо от того, цел ли он или сломан.

Изменить: вот абстрактные изображения, которые могут сделать его более ясным. http://1drv.ms/1toMHay Внутренний круг разорван, внешний - нормально. HoughCircles может обнаружить оба круга, хотя внутренний не должен обнаруживаться.

Идея состоит в том, что у меня есть эталонное изображение с двумя неповрежденными кругами, чтобы определить правильный радиус, порог и другие параметры для функции hough circle, чтобы убедиться, что они находятся с hough кругами. С этими параметрами следует проанализировать другие изображения, чтобы увидеть, содержат ли они также два неповрежденных круга или хотя бы один круг выглядит как внутренний круг из предоставленного мной изображения.

Загруженные изображения Я загрузил несколько реальных изображений, чтобы было понятнее, чего я пытаюсь достичь. http://1drv.ms/1nhJJQ9 Эти изображения сделаны в двух разных световых ситуациях: с прямым и непрямым светом. В каждом наборе есть «неповрежденное» изображение и несколько битых. Теперь мне нужно определить, цело ли изображение или нет, и мой первый подход - посмотреть, целы ли два круга или как-то потрепаны. Возможно ли это с этими изображениями или есть способ лучше?


person CactusJack    schedule 21.08.2014    source источник
comment
Вы должны дать ссылку на пару изображений. Это поможет нам помочь вам :)   -  person biquette    schedule 21.08.2014
comment
возможно, вы можете попробовать мой ответ из http://stackoverflow.com/questions/20698613/detect-semi-circle-in-opencv/20706100#20706100 и принимайте только около 100% кругов. но ответ diip_thomas с использованием контуров может быть проще;)   -  person Micka    schedule 21.08.2014


Ответы (2)


Вариант 1

Слишком уж определить, есть ли круги, я бы придерживался функции houghCircles в OpenCV. Чтобы определить, не потрепаны ли они или нет, я бы посоветовал использовать контуры.

Если вы используете функцию OpenCV findContours(), вы получите список всех "форм" на вашем изображении. Затем вы можете проверить, соответствует ли какой-либо из этих контуров вашим ожидаемым критериям. В круге должно быть постоянное соотношение между contourArea() и _ 3_.

Пример использования findContours() и проверки площади каждого контура:

//Find and draw contours
vector <vector<Point> > contours; // Vector for storing contour
vector<Vec4i> hierarchy;
findContours(binaryImage, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

for (int i = 0; i < contours.size(); i++) {
 float area = contourArea(contours[i], false);
 if (area > 300) {
  drawContours(inputImage, contours, i, Scalar(0, 0, 255), 2, 8, hierarchy);
 }
}

Убедитесь, что вы используете двоичное изображение в качестве входных данных. В этом примере красным цветом рисуются все контуры изображения, размер которых превышает 300 в contourArea.

Вариант 2

Другой вариант - придерживаться houghCircles(), но затем проверить пиксели вокруг найденного круга. Если вы развернете пиксели в радиусе от центральной точки и посчитаете, сколько пикселей белого цвета в вашем двоичном изображении, вы можете создать процент, который может описать, насколько хорошо ваш houghCircle соответствует изображению.

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

for(int i=0;i<binaryImage.rows;i++) {
    for(int j=0;j<binaryImage.cols;j++) {
       std::cout << (int)binaryImage.at<uchar>(i,j)<< ",";
    }
    std::cout << "\n";
}
person diip_thomas    schedule 21.08.2014
comment
Танки для информации. Я попробовал, но проблема в том, что круги не так четкие, как кажется на моем образце изображения. Это приводит к гораздо большему количеству повреждений, чем можно было бы ожидать. Я взял и загрузил несколько реальных изображений, чтобы было понятнее, чего я пытаюсь достичь и как выглядят исходные изображения. - person CactusJack; 22.08.2014
comment
Хорошие примеры изображений, немного проясняющие проблему. Вы можете работать над ответом, который я предложил, но тогда ваша проблема заключается в том, чтобы получить двоичное изображение, которое выглядит как первое загруженное вами изображение. Это было бы само по себе почти новым вопросом. Напишу другой вариант в другом ответе - person diip_thomas; 22.08.2014
comment
Большое тебе спасибо. Это хорошая идея, но вы правы, тогда основная проблема заключается в создании приемлемого двоичного образа. Я попытался сделать это, но в двоичном изображении много шума, и вы не можете сказать, что принадлежит обводке круга, а что нет. Я буду продолжать попытки. :) - person CactusJack; 22.08.2014

как сказал biqutte, с некоторыми изображениями вы получите лучшую помощь, но моя идея в том, что если вы знаете радиус и центральное положение, вы можете написать небольшую функцию, которая оценивает цвет пикселя по кругу, вы можете установить свой собственный край . а вы можете использовать функцию OpenCV cv::Termcriteria для повышения точности вашего алгоритма.

person Engine    schedule 21.08.2014