2016-08-03 2 views
2

У меня два изображения, второе - первое после модификации. Я нахожу контуры двух изображений, а затем проверяю, есть ли какие-либо контуры. Проблема в том, что, несмотря на то, что контуры одинаковые (контуры рисунка одного изображения и другие дают одинаковые результаты), проверяя, что никогда не становится истинным, что один контур равен любому другому.Как проверить, одинаковы ли контуры?

Код: Нахождение контуры:

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--; 
    } 
} 

Что я делаю неправильно? Является ли этот способ проверки сходства контуров неправильным? Если да, то как я могу проверить, совпадают ли два контура? Как бы вы проверили совпадение контуров, если вам нужно?

Первое изображение:

enter image description here

Второе изображение:

enter image description here

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

...

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--; 
    } 
} 

ответ

2

Оператор равенства == не работает для объектов, как она работает для примитивов.

Для int с, char с, boolean с, и т.д., сравнивающих с == проверки, если их значения равны. Для объектов он проверяет, относятся ли эти две переменные к одному и тому же объекту, а не к тому, что поля внутри объектов одинаковы. Для того, чтобы проверить на объекты эквивалентными, есть метод .equals(), который будет использоваться как это:

if (contours1.get(i).equals(contours2.get(i))) 

Однако, это будет по умолчанию такое же поведение, как ==, проверяя, если две переменные ссылаются на то же самое объект. В вашем классе MatOfPoint вам необходимо переопределить метод .equals(), чтобы определить, как он должен проверять, что два объекта являются «равными».

1

Давным-давно у меня была аналогичная проблема, и я использовал этот алгоритм: сглаживание многомасштабных кривых для обобщенного распознавания образов (MSGPR). См. link1 и link2.

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

+0

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

+0

Из опыта, контуры никогда не точны из-за процесса дискретизации. Таким образом, всегда будут какие-то пиксели, которые могут быть разными или нет, это тот же самый порядок. В этом случае этот документ имеет смысл. – FiReTiTi

+0

Я понимаю вашу точку зрения, но в моей ситуации они совершенно одинаковы, потому что второе изображение является только измененным первым, оно имеет отверстия в белых зонах. Моя задача - найти, что эти дыры пересекают границы белых зон и меняют внешние контуры, и я решил эту проблему (я отредактировал вопрос), но мой метод довольно трудоемкий (хотя и отменяет любую способность к ошибкам), поэтому я думая о более прямом и более быстром способе проверки соответствия контуров или только оптимизации кода, который я дал. Если мои контуры не будут на 100% одинаковыми, ваша данная статья будет ответом. –

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