У меня недавно была проблема с перемещаемым jQuery ui элемент. Это вело себя правильно в Firefox, но не Safari. После тонны метода проб и ошибок фиксация должна была переместить мои ссылки css выше ссылок JavaScript в голове. Очень нечетный, но теперь станет моей общепринятой практикой.
Там есть множество примеров реализации .. 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) );
| | | |
--------------------
Возможно, лучший способ взглянуть на это - как создать выходной пиксель расширения. Для соответствующего пикселя в изображении выровняйте элемент структурирования так, чтобы начало элемента структурирования находилось в этом пикселе изображения. Если есть какое-либо перекрытие, установите выходной пиксель расширения в этом месте на 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.
/* 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 */