2015-03-29 5 views
8

Я пишу программное обеспечение, которое обнаруживает контур изображения, уменьшает его до «одного пикселя», а затем выполняет операции над результирующим контуром. Моя надежда состоит в том, чтобы в конечном итоге получить следующее:Thinning a line

enter image description here

Я написал программное обеспечение, которое автоматически определяет RGBA цвета, преобразует его в HSB, просит предел, который устанавливает пиксель является ли план или нет (как правило, некоторые значение около 0,25 и проверку значения B (яркости), а затем сохраняет true или false в двумерном массиве логических значений (true - контур, false - нет). Это доводит меня до стадии 2 просто отлично. В настоящее время я застрял на этапе 3, и в настоящее время пытаюсь добиться следующим:

http://i.imgur.com/BTs6miR.png

Вот мой текущий код, где переменной outline[][] оригинального 2d массив истин/falses (этап 2) и thinned[][] является план на стадии 3.

public void thinOutline() { 
    thinned = new boolean[outline.length][outline[0].length]; 
    for (int x = 0; x < thinned.length; x++) 
     for (int y = 0; y < thinned[0].length; y++) { 
      if (x > 0 && x < thinned.length - 1 && y > 0 && y < thinned[0].length - 1) 
       if (!thinned[x + 1][y] && !thinned[x - 1][y] && !thinned[x][y + 1] && !thinned[x][y - 1] && outline[x][y]) 
        thinned[x][y] = true; 
       else 
        thinned[x][y] = false; 
      else 
       thinned[x][y] = outline[x][y]; 
     } 
} 
+1

Это не скрипт, который находит границы, а затем удаляет их. Если это так, вы можете просто запустить этот сценарий много раз, пока он больше не найдет границ, и при этом вы должны иметь этот желаемый эффект. –

ответ

0

Я придумал довольно простое решение, которое работает достаточно хорошо для моих целей. У меня есть 3 массива, outline[][], thinned[][] и thinIteration[][]. outline[][] и thinned[][] оба устанавливаются, когда изображение загружается, как объяснено в моем вопросе (этапы 1 и 2). thinIteration[][] затем загружается партиями пикселей, которые необходимо разбавлять и считаться «пограничными» пикселями. Затем функция стирает эти пиксели, и если она удаляет любые пикселей, он перезапускает метод. Он продолжает делать этот цикл, пока не найдет больше пикселей для тонких.

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

public void thinOutline() { 
    boolean didThinIteration = false; 
    for (int x = 1; x < originalWidth - 1; x++) 
     for (int y = 1; y < originalHeight - 1; y++) { 
      int numOfBorders = (thinned[x - 1][y] ? 1 : 0) + (thinned[x + 1][y] ? 1 : 0) + (thinned[x][y + 1] ? 1 : 0) + (thinned[x][y - 1] ? 1 : 0); 
      int numOfDiagonals = (thinned[x - 1][y + 1] ? 1 : 0) + (thinned[x + 1][y + 1] ? 1 : 0) + (thinned[x - 1][y - 1] ? 1 : 0) + (thinned[x + 1][y - 1] ? 1 : 0); 

      boolean thin = thinned[x][y] && numOfBorders > 1 && numOfBorders < 4 && numOfDiagonals > 1 && numOfDiagonals < 4; 

      thinIteration[x][y] = thin; 
      if (thin && !didThinIteration) 
       didThinIteration = true; 
     } 

    for (int x = 0; x < originalWidth; x++) 
     for (int y = 0; y < originalHeight; y++) 
      if (thinIteration[x][y]) 
       thinned[x][y] = false; 

    if (didThinIteration) 
     thinOutline(); 
} 
+0

Вау ... это довольно много булевых условий;) Предположим, что математика в порядке, однако у меня есть другой вопрос: каков максимальный размер этих массивов? У вас максимальный размер для изображений? –