адаптивный эллиптический структурирующий элемент в MATLAB - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь создать адаптивный эллиптический структурирующий элемент для изображения, чтобы расширить или размыть его.Я пишу этот код, но, к сожалению, все структурирующие элементы имеют размер ones(2*M+1).

I = input('Enter the input image: ');
M = input('Enter the maximum allowed semi-major axes length: ');

% determining ellipse parameteres from eigen value decomposition of LST

row = size(I,1);
col = size(I,2);
SE = cell(row,col);
padI = padarray(I,[M M],'replicate','both');
padrow = size(padI,1);
padcol = size(padI,2);

for m = M+1:padrow-M
   for n = M+1:padcol-M

      a = (l2(m-M,n-M)+eps/l1(m-M,n-M)+l2(m-M,n-M)+2*eps)*M;
      b = (l1(m-M,n-M)+eps/l1(m-M,n-M)+l2(m-M,n-M)+2*eps)*M;

      if e1(m-M,n-M,1)==0
         phi = pi/2;
      else
         phi = atan(e1(m-M,n-M,2)/e1(m-M,n-M,1));
      end

      % defining structuring element for each pixel of image

      x0 = m;  
      y0 = n;
      se = zeros(2*M+1);
      row_se = 0;
      for i = x0-M:x0+M
         row_se = row_se+1;
         col_se = 0;
         for j = y0-M:y0+M
            col_se = col_se+1;
            x = j-y0;
            y = x0-i;
            if ((x*cos(phi)+y*sin(phi))^2)/a^2+((x*sin(phi)-y*cos(phi))^2)/b^2 <= 1
               se(row_se,col_se) = 1;
            end
         end
      end

      SE{m-M,n-M} = se;
   end
end

a, b и phi - длина полуоси и полуосновы, а угол - уголмежду a и осью x.

Я использовал 2 функции MATLAB для вычисления тензора локальной структуры изображения, а затем его собственные значения и собственные векторы для каждого пикселя.Это матрицы l1, l2, e1 и e2.

1 Ответ

0 голосов
/ 25 апреля 2018

Это бит вашего кода, который я не понял:

a = (l2(m-M,n-M)+eps/l1(m-M,n-M)+l2(m-M,n-M)+2*eps)*M;
b = (l1(m-M,n-M)+eps/l1(m-M,n-M)+l2(m-M,n-M)+2*eps)*M;

Я упростил выражение для b до (просто удалив индексирование):

b = (l1+eps/l1+l2+2*eps)*M;

Для l1 и l2 в нормальном диапазоне мы получаем:

b =(approx)= (l1+0/l1+l2+2*0)*M = (l1+l2)*M;

Таким образом, b может легко быть больше, чем M, что я не думаю,это твое намерение.eps в этом случае также не защищает от деления на ноль, что обычно является целью добавления eps: если l1 равно нулю, eps/l1 равно Inf.

Lookingв этом выражении мне кажется, что вы намеревались это вместо этого:

b = (l1+eps)/(l1+l2+2*eps)*M;

Здесь вы добавляете eps к каждому из собственных значений, делая их гарантированно ненулевыми (тензор структуры симметричен, положительный полуопределенный).Затем вы делите l1 на сумму собственных значений и умножаете на M, что приводит к значению между 0 и M для каждой из осей.

Итак, это кажетсячтобы быть случай неправильной скобки.

Просто для записи, это то, что вам нужно в вашем коде:

a = (l2(m-M,n-M)+eps ) / ( l1(m-M,n-M)+l2(m-M,n-M)+2*eps)*M;
b = (l1(m-M,n-M)+eps ) / ( l1(m-M,n-M)+l2(m-M,n-M)+2*eps)*M;
                     ^   ^
                added parentheses

Обратите внимание, что вы можете упростить свой код, определив,вне циклов:

[se_x,se_y] = meshgrid(-M:M,-M:M);

Внутренние два цикла, более i и j, для построения se могут быть записаны просто как:

se = ((se_x.*cos(phi)+se_y.*sin(phi)).^2)./a.^2 + ...
     ((se_x.*sin(phi)-se_y.*cos(phi)).^2)./b.^2 <= 1;

(Обратите внимание на операторы .* и .^, которые выполняют поэлементное умножение и мощность.)

Еще одно небольшое улучшение происходит от понимания того, что phi сначала вычисляется из e1(m,n,1) и e1(m,n,2),а затем используется в вызовах на cos и sin.Если предположить, что собственный вектор правильно нормализован, то

cos(phi) == e1(m,n,1)
sin(phi) == e1(m,n,2)

Но вы всегда можете убедиться, что они нормализованы:

cos_phi = e1(m-M,n-M,1);
sin_phi = e1(m-M,n-M,2);
len = hypot(cos_phi,sin_phi);
cos_phi = cos_phi / len;
sin_phi = sin_phi / len;
se = ((se_x.*cos_phi+se_y.*sin_phi).^2)./a.^2 + ...
     ((se_x.*sin_phi-se_y.*cos_phi).^2)./b.^2 <= 1;

Учитывая, что тригонометрические операции довольно дороги, это должно ускоритьВаш код немного.

...