У меня два изображения, второе - первое после модификации. Я нахожу контуры двух изображений, а затем проверяю, есть ли какие-либо контуры. Проблема в том, что, несмотря на то, что контуры одинаковые (контуры рисунка одного изображения и другие дают одинаковые результаты), проверяя, что никогда не становится истинным, что один контур равен любому другому.Как проверить, одинаковы ли контуры?
Код: Нахождение контуры:
List<MatOfPoint> contours1 = new ArrayList<>();
List<MatOfPoint> contours2 = new ArrayList<>();
Imgproc.findContours(contours1mat, contours1, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
Imgproc.findContours(contours2mat, contours2, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
Проверка контуров (она никогда не делает переменную матч так):
for(int i = 0; i < contours1.size(); i++)
{
boolean match = false;
for (int j = 0; j < contours2.size(); j++)
{
if (contours1.get(i) == contours2.get(j))
{
//never hits that place, despite passing through all contours
match = true;
break;
}
}
if (!match)
{
contours1.remove(i);
i--;
}
}
Что я делаю неправильно? Является ли этот способ проверки сходства контуров неправильным? Если да, то как я могу проверить, совпадают ли два контура? Как бы вы проверили совпадение контуров, если вам нужно?
Первое изображение:
Второе изображение:
Логика второго изображения является то, что это первое изображение, но с отверстиями, пробитых в Это. Я проверяю, если эти отверстия пересекают сторону белой зоны, если это не так, должны быть два одинаковых контура в первом и втором изображении. Я только нахожу внешние контуры, поэтому размер контура одинаковый на обоих изображениях.
...
UPDATE !!! Этот код дает мне желаемый результат, но проблема в том, что это действительно занимает много времени, и, очевидно, есть огромная комната для улучшения самого алгоритма (возможно, некоторое приближение контуров может быть выполнено до проверки) или метод, который я использую. Я очень надеюсь, что есть простой прямой результат для решения моей проблемы. Код:
for(int i = 0; i < contours1.size(); i++)
{
boolean match = true;
for (int j = 0; j < contours2.size(); j++)
{
if (contours1.get(i).toArray().length == contours2.get(j).toArray().length)
{
boolean match2 = true;
for (int k = 0; k < contours1.get(i).toArray().length; k++)
{
if ((contours1.get(i).toArray()[k].x != contours2.get(j).toArray()[k].x) ||
(contours1.get(i).toArray()[k].y != contours2.get(j).toArray()[k].y))
{
match2 = false;
}
}
if (match2)
{
match = true;
break;
}
}
else
match = false;
}
if (!match)
{
contours1.remove(i);
i--;
}
}
Статья, которую вы мне дали, очень интересна и полезна, но она предназначена для проверки между двумя похожими, не одинаковыми контурами. В моей ситуации у меня есть совершенно похожие контуры. Несмотря на это, опять же, спасибо за эту статью, действительно захватывающе. –
Из опыта, контуры никогда не точны из-за процесса дискретизации. Таким образом, всегда будут какие-то пиксели, которые могут быть разными или нет, это тот же самый порядок. В этом случае этот документ имеет смысл. – FiReTiTi
Я понимаю вашу точку зрения, но в моей ситуации они совершенно одинаковы, потому что второе изображение является только измененным первым, оно имеет отверстия в белых зонах. Моя задача - найти, что эти дыры пересекают границы белых зон и меняют внешние контуры, и я решил эту проблему (я отредактировал вопрос), но мой метод довольно трудоемкий (хотя и отменяет любую способность к ошибкам), поэтому я думая о более прямом и более быстром способе проверки соответствия контуров или только оптимизации кода, который я дал. Если мои контуры не будут на 100% одинаковыми, ваша данная статья будет ответом. –