Определение зеленых кружков на этом изображении

В настоящее время я сделал изображение, которое состоит из черных и зеленых точек ..... Я сделал его печать, а затем щелкнул по нему своей камерой ..... После этого я сделал программу для сканирования этого изображения в opencv. Вот изображение:

Это код

    image = imread("ImageTryse.jpg", 1); // Read the image
cv::resize(image, image, Size(800, 800), 0, 0, cv::INTER_CUBIC);
Mat image_gray = IncreaseContrast(image);
cvtColor(image_gray, image_gray, CV_BGR2GRAY);
vector<vec3f> circles1;
HoughCircles(image_gray, circles1, CV_HOUGH_GRADIENT, 2, 10, 100, 22, 10, 17);

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

 Dainius Šaltenis14 июл. 2016 г., 00:37
Я решил вашу проблему с помощью кода и примеров и отредактировал ответ. Не забудьте проверить!
 Bruce David Wilner13 июл. 2016 г., 20:10
@ Beaker, это полная чушь. Преобразование BGR <-> HSV является полностью биективным.
 beaker13 июл. 2016 г., 18:54
На самом деле, я думаю, что это может быть легче обнаружить в BGR, чем в HSV. Вы пытались определить соотношение зеленого компонента к красному (или синему) компоненту обнаруженных дисков?

Ответы на вопрос(2)

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

Диапазон для HSV составляет от (32,22,0) до (103,142,160)

Я надеюсь, что это решает проблемы. :)

Решение Вопроса

InRange (в C ++ это было быcv2.InRange, Джава-Core.InRange). В этой функции вы предоставляете дваScalar объекты: один начинает цвет BGR из диапазона цветов, другой - конец. Он вернет вам маску белых пикселей: белый цвет находится в диапазоне, черный - нет. Дополнительная информацияВОТ, Я бы порекомендовал вам позвонитьInRange доHoughCircles, было бы легче определить, какие объекты зеленого цвета являются кругами, а не какие круги зеленого цвета.

Я опробовал этот метод для решения вашей проблемы:

Сначала я выполняю функцию InRange с начальными значениями HSVScalar(37, 38, 70) и окончаниеScalar(85, 255, 200), Обратите внимание, что вы помещаете не значения RGB или BGR в Scalar, это цвет HSV (в диапазоне H (0-180), S (0-255), V (0-255), как написано вЭТОТ ответ):

Во-вторых, я выполняю алгоритм HoughCircles, как вы делаете в своем коде:

Как видите, есть один кружок, где его не должно быть, также кружки могут быть разными по размеру на обеих картинках. Я настоятельно рекомендую вам поиграть со значениями функции InRange, чтобы улучшить выбор цвета, сделать круги более круглыми и более совершенными, а также HoughCircles, чтобы избежать случайных и ненужных кругов, поскольку я получил один в середине последнего изображения. Кроме того, я бы предложил вам поэкспериментировать с алгоритмом Канни (детектором краев Канни), чтобы очистить центры этих объектов, возможно, тогда ваши результаты улучшатся.

Код написан на Java, но вы должны легко понять его, поскольку ваша задача в основном связана с функцией InRange:

Mat src = new Mat();
Mat circles = new Mat();
Mat result;

Utils.bitmapToMat(Image, src);
Imgproc.cvtColor(src, src, Imgproc.COLOR_BGR2HSV);

Core.inRange(src, new Scalar(37, 38, 70), new Scalar(85, 255, 200), src);
Imgproc.HoughCircles(src, circles, Imgproc.CV_HOUGH_GRADIENT, 2, 30, 100, 22, 10, 17);

result = new Mat(src.rows(), src.cols(), CvType.CV_8UC1, new Scalar(0,0,0));
for (int i = 0; i < circles.cols(); i++)
{
    double[] circle = circles.get(0, i);
    if (circle == null) break;
    Point center = new Point(Math.round(circle[0]), Math.round(circle[1]));
    int radius = (int)Math.round(circle[2]);
    Imgproc.circle(result, center, radius, new Scalar(255, 0, 0));
}
return result;

Наконец, этот алгоритм даже с правильными значениями может быть не идеальным. Я думаю, что можно получить действительно великолепные или идеальные результаты с правильными значениями (к сожалению, у меня не было много времени, чтобы выяснить их, поэтому я оставляю это вам), но если вам нужен идеальный результат, я бы предложил вам поэкспериментировать в более широком спектре. Например, вызов функции Canny на цветном изображении (как вы указали) может дать вам очень точные контуры кругов и других объектов. Затем, например, вы можете выполнить функцию HoughCircles для этих контуров и, имея данные о них, очистить все пиксели за пределами окружностей. Затем с InRange вы можете проверить цвета кругов и разобраться с ними ... Но это только теоретически. Попробуйте все, что приходит на ум. Этот эксперимент может дать вам более правильный результат, чем обновленный текущий. Удачи!

 Utkarsh Dixit14 июл. 2016 г., 03:49
Спасибо, я понимаю Java и могу перенести его на C ++ ....
 Dainius Šaltenis14 июл. 2016 г., 14:24
На самом деле у меня очень минимальный опыт работы с этой функцией. Я бы посоветовал вам найти палитру цветов HSV в Интернете и попытаться найти приблизительный диапазон желаемого цвета. Это может занять несколько раз, чтобы найти баланс, но это единственный способ, о котором я могу думать.
 Utkarsh Dixit14 июл. 2016 г., 10:37
Я знал о функции inrange прежде, но я не смог найти значения для этого .... Можете ли вы помочь мне найти идеальные значения ..... Или вы можете предложить любой способ, которым я могу это сделать.

Ваш ответ на вопрос