реализовывая эрозию, расширение в C, C++

У меня недавно была проблема с перемещаемым jQuery ui элемент. Это вело себя правильно в Firefox, но не Safari. После тонны метода проб и ошибок фиксация должна была переместить мои ссылки css выше ссылок JavaScript в голове. Очень нечетный, но теперь станет моей общепринятой практикой.

8
задан FiReTiTi 29 December 2015 в 01:30
поделиться

4 ответа

Там есть множество примеров реализации .. Google - ваш друг: )

РЕДАКТИРОВАТЬ
Ниже приводится псевдокод процесса (очень похожий на выполнение свертки в 2D). Я уверен, что есть более умный способ сделать это:

// grayscale image, binary mask
void morph(inImage, outImage, kernel, type) {
 // half size of the kernel, kernel size is n*n (easier if n is odd)
 sz = (kernel.n - 1 ) / 2;

 for X in inImage.rows {
  for Y in inImage.cols {

   if ( isOnBoundary(X,Y, inImage, sz) ) {
    // check if pixel (X,Y) for boundary cases and deal with it (copy pixel as is)
    // must consider half size of the kernel
    val = inImage(X,Y);       // quick fix
   }

   else {
    list = [];

    // get the neighborhood of this pixel (X,Y)
    for I in kernel.n {
     for J in kernel.n {
      if ( kernel(I,J) == 1 ) {
       list.add( inImage(X+I-sz, Y+J-sz) );
      }
     }
    }

    if type == dilation {
     // dilation: set to one if any 1 is present, zero otherwise
     val = max(list);
    } else if type == erosion {
     // erosion: set to zero if any 0 is present, one otherwise
     val = min(list);
    }
   }

   // set output image pixel
   outImage(X,Y) = val;
  }
 }
}

Приведенный выше код основан на этом учебнике (проверьте исходный код в конце страницы).


EDIT2 :

list.add (inImage (X + I-sz, Y + J-sz));

Идея состоит в том, что мы хотим наложить маску ядра (размером nxn) с центром в sz (половина размера маски) на текущий пиксель изображения, расположенный в (X, Y), а затем просто получите интенсивности пикселей, где значение маски равно единице (мы добавляем их в список). После извлечения всех соседей для этого пикселя мы устанавливаем для пикселя выходного изображения максимальное значение из этого списка (максимальная интенсивность) для расширения и минимальное значение для эрозии (конечно, это работает только для изображений в градациях серого и двоичной маски)
Предполагается, что индексы X / Y и I / J в приведенном выше утверждении начинаются с 0. Если хотите, вы всегда можете переписать индексы I / J, используя половину размера маски (от -sz до + sz) с небольшим изменением (как используется в учебнике, на который я ссылался) ...


Пример :
Рассмотрим эту маску ядра 3x3, размещенную и центрированную на пикселе (X, Y), и посмотрите, как мы обходим окрестности вокруг нее:

 --------------------
|      |       |     |    sz = 1;
 --------------------     for (I=0 ; I<3 ; ++I)
|      | (X,Y) |     |      for (J=0 ; J<3 ; ++J)
 --------------------         vect.push_back( inImage.getPixel(X+I-sz, Y+J-sz) );
|      |       |     |
 --------------------
13
ответ дан 5 December 2019 в 10:42
поделиться

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

Это можно сделать, просто перебирая каждый пиксель в изображении и проверяя, правильно ли сдвинут элемент структурирования. накладывается на изображение. Это означает, что у вас, вероятно, будет 4 вложенных цикла: x img, y img, x se, y se. Итак, для каждого пикселя изображения вы перебираете пиксели структурирующего элемента и смотрите, есть ли перекрытия. Возможно, это не самый эффективный алгоритм, но он, вероятно, самый простой.

Кроме того, я думаю, что ваш пример неверен. Расширение зависит от происхождения структурирующего элемента. Если начало координат ...

вверху слева ноль: вам нужно сдвинуть изображение (-1, -1), (-1,0) и (0, -1), получив:

1 1 1 0 0
1 1 0 0 0
1 1 0 0 0
1 0 0 0 0
0 0 0 0 0 

в нижний правый: вам нужно сместить изображение (0,0), (1,0) и (0,1), получив:

0 0 0 0 0
0 1 1 1 0
0 1 1 0 0
0 1 1 0 0
0 1 0 0 0

MATLAB использует floor ((size (SE) +1) / 2) в качестве происхождение SE, поэтому в этом случае он будет использовать верхний левый пиксель SE. Вы можете проверить это, используя функцию imdilate MATLAB.

2
ответ дан 5 December 2019 в 10:42
поделиться
/* structure of the image variable
 * variable n stores the order of the square matrix */

typedef struct image{
        int mat[][];
        int n;
        }image;


/* function recieves image "to dilate" and returns "dilated"*
 * structuring element predefined:
 *             0  1  0
 *             1  1  1
 *             0  1  0
 */

image* dilate(image* to_dilate)
{
       int i,j;
       int does_order_increase;
       image* dilated;

       dilated = (image*)malloc(sizeof(image));
       does_order_increase = 0;

/* checking whether there are any 1's on d border*/       

       for( i = 0 ; i<to_dilate->n ; i++ )
       {
            if( (to_dilate->a[0][i] == 1)||(to_dilate->a[i][0] == 1)||(to_dilate->a[n-1][i] == 1)||(to_dilate->a[i][n-1] == 1) )
            {
                does_order_increase = 1;
                break;
            }
       }

/* size of dilated image initialized */       

       if( does_order_increase == 1)
           dilated->n = to_dilate->n + 1;
       else
           dilated->n = to_dilate->n;

/* dilating image by checking every element of to_dilate and filling dilated *
 * does_order_increase serves to cope with adjustments if dilated 's order increase */

       for( i = 0 ; i<to_dilate->n ; i++ )
       {
            for( j = 0 ; j<to_dilate->n ; j++ )
            {
                 if( to_dilate->a[i][j] == 1)
                 {
                     dilated->a[i + does_order_increase][j + does_order_increase] = 1;
                     dilated->a[i + does_order_increase -1][j + does_order_increase ] = 1;
                     dilated->a[i + does_order_increase ][j + does_order_increase -1] = 1;
                     dilated->a[i + does_order_increase +1][j + does_order_increase ] = 1;
                     dilated->a[i + does_order_increase ][j + does_order_increase +1] = 1;
                 }
            }
       }

/* dilated stores dilated binary image */

       return dilated;
}

/* end of dilation */ 
0
ответ дан 5 December 2019 в 10:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: