Обнаружение нечеткого импульсного шума в Matlab

Я пытаюсь реализовать метод обнаружения нечеткого импульсного шума в Matlab. Я определяю окно размером 3*3, которое для каждого неграничного пикселя изображения в градациях серого будет вычислять различные градиенты во всех 8 возможных соседях центрального пикселя, проверять нечеткие правила и определять, является ли этот пиксель шумным или нет. Но он просто проходит через первый пиксель и правильно его вычисляет; для второго пикселя я получаю следующую ошибку. Кто-нибудь может помочь, пожалуйста? Кроме того, я пытаюсь определить функцию для расчета градиентов, возможно ли определить такую ​​​​функцию для всех направлений? ошибка :

Показатель превышает размеры матрицы.

Ошибка в Main (строка 29) g2 = double(img_temp(r, c+1) - img_temp(r,c));

и вот мой код:

close all
clc

[file, path] = uigetfile('*.*' , 'Open an image');
filename = strcat(path, file);
img = (imread(filename));

dim = ndims(img);

if (dim==3)
    img = rgb2gray(img);

end

figure, imshow(img);

k = 1;
[row , col] = size(img);
 for r=2:row-1
     largeCount = 0;

     for c=2:col-1
         img_temp = img(r-1:r+1, c-1:c+1);

     %% Gradient Calculation in Direction : N 
       g0 = double(img_temp(r-1,c) - img_temp(r,c));
       g1 = double(img_temp(r, c-1) - img_temp(r,c));
       g2 = double(img_temp(r, c+1) - img_temp(r,c));

         g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end

     %% Gradient Calculation in Direction : NE 
    g0 = double(img_temp(r-1 , c+1) - img_temp(r,c));
     g1 = double(img_temp(r-1, c-1) - img_temp(r,c));
     g2 = double(img_temp(r+1 , c+1) - img_temp(r,c));

    g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end

     %% Gradient Calculation in Direction : E
     g0 = double(img_temp(r,c+1) - img_temp(r,c));
     g1 = double(img_temp(r-1,c) - img_temp(r,c));
     g2 = double(img_temp(r+1 ,c) - img_temp(r,c));


     g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end

     %% Gradient Calculation in Direction : SE 
     g0 = double(img_temp(r+1, c+1) - img_temp(r,c));
     g1 = double(img_temp(r-1 , c+1) - img_temp(r,c));
     g2 = double(img_temp(r+1 , c-1) - img_temp(r,c));

     g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end

     %% Gradient Calculation in Direction : S 
     g0 = double(img_temp(r+1, c) - img_temp(r,c));
     g1 = double (img_temp(r , c+1) - img_temp(r,c));
     g2 = double(img_temp(r , c-1) - img_temp(r,c));

     g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end

     %% Gradient Calculation in Direction : SW 
     g0 = double(img_temp(r+1, c-1) - img_temp(r,c));
     g1 = double(img_temp(r+1 , c+1) - img_temp(r,c));
     g2 = double(img_temp(r-1, c-1) - img_temp(r,c));


     g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end

     %% Gradient Calculation in Direction : W 
     g0 = double(img_temp(r,c-1) - img_temp(r,c));
     g1 = double(img_temp(r+1, c) - img_temp(r,c));
     g2 = double(img_temp(r-1, c) - img_temp(r,c));


     g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end

     %% Gradient Calculation in Direction : NW 
     g0 = double(img_temp(r-1,c-1) - img_temp(r,c));
     g1 = double(img_temp(r+1 , c-1) - img_temp(r,c));
     g2 = double(img_temp(r-1 , c+1) - img_temp(r,c));


     g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end
     k = k+1;
     end

     %% if largeCount > 4 then the pixel is noisy for sure
     if largeCount> 4 
      %% Add the pixel value to histogram
      out(r,c)= 0;
     else 
      %% Don't change pixel value

      output(r,c) = (temp(r,c));
     end

 end

 figure ; imshow(output);

РЕДАКТИРОВАТЬ :

Однако я изменил свой код, пока я запускаю следующий код, он приостанавливается (стек вызовов функций: ismemeber) и не показывает мне img_out. Я получаю эту ошибку:

69 [sortuAuB,IndSortuAuB] = sort([uA;uB]);

и вот мой отредактированный код:

close all
clc

[file, path] = uigetfile('*.*' , 'Open an image');
filename = strcat(path, file);
img = (imread(filename));

dim = ndims(img);

if (dim==3)
    img = rgb2gray(img);

end

figure, imshow(img);

k = 1;
out = readfis('NoiseDetection.fis');

[row , col] = size(img);

img_out = zeros(row , col , 'uint8');

 for r=2:row-1
     largeCount = 0;

     for c=2:col-1
         img_temp = img(r-1:r+1, c-1:c+1);

     %% Gradient Calculation in Direction : N 
       g0 = double(img_temp(1,2) - img_temp(2,2));
       g1 = double(img_temp(2,1) - img_temp(2,2));
       g2 = double(img_temp(2,3) - img_temp(2,2));

     g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end

     %% Gradient Calculation in Direction : NE 
     g0 = double(img_temp(1,3) - img_temp(2,2));
     g1 = double(img_temp(1,1) - img_temp(2,2));
     g2 = double(img_temp(3,3) - img_temp(2,2));

     g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end

     %% Gradient Calculation in Direction : E
     g0 = double(img_temp(2,3) - img_temp(2,2));
     g1 = double(img_temp(1,2) - img_temp(2,2));
     g2 = double(img_temp(3,2) - img_temp(2,2));

     g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end

     %% Gradient Calculation in Direction : SE 
     g0 = double(img_temp(3,3) - img_temp(2,2));
     g1 = double(img_temp(1,3) - img_temp(2,2));
     g2 = double(img_temp(3,1) - img_temp(2,2));


     g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end

     %% Gradient Calculation in Direction : S 
     g0 = double(img_temp(3, 2)- img_temp(2,2));
     g1 = double(img_temp(2, 3)- img_temp(2,2));
     g2 = double(img_temp(2 ,1)- img_temp(2,2));

     g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end

     %% Gradient Calculation in Direction : SW 
     g0 = double(img_temp(3,1) - img_temp(2,2));
     g1 = double(img_temp(3,3) - img_temp(2,2));
     g2 = double(img_temp(1,1) - img_temp(2,2));


     g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end

     %% Gradient Calculation in Direction : W 
     g0 = double(img_temp(2,1)- img_temp(2,2));
     g1 = double(img_temp(3,2)- img_temp(2,2));
     g2 = double(img_temp(1,2)- img_temp(2,2));


     g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end

     %% Gradient Calculation in Direction : NW 
     g0 = double(img_temp(1,1)- img_temp(2,2));
     g1 = double(img_temp(3,1)- img_temp(2,2));
     g2 = double(img_temp(1,3)- img_temp(2,2));


     g_weight = max (max ( evalfis([g0 g1 0],out) , evalfis([g0 0 g2],out)), evalfis([g0 g1 g2],out) );
     if g_weight >128
         largeCount = largeCount+1;
     end
     %% if largeCount > 4 then the pixel is noisy for sure
      if largeCount> 4 

     %% Add the pixel value to histogram
      img_out(r,c)=0;

       else 
      %% Don't change pixel value

      img_out(r,c) = img_temp(2,2);
      end
    end
     k = k+1;
 end

 figure ; imshow(img_out);

person Shin    schedule 23.05.2016    source источник


Ответы (1)


Вы извлекаете окрестность размером 3 x 3 пикселя для каждого центрального пикселя изображения. Однако при оценке градиентов вы используете систему координат по отношению к исходному изображению, а не саму область извлеченных пикселей.

Поэтому все ваши расчеты градиента неверны. Это очевидно из-за того, что r и c могут выходить за пределы значений 3, которые являются наибольшим измерением строк и столбцов вашего района.

Самым простым решением было бы исправить все операции индексации в вашей окрестности 3 x 3 пикселя, чтобы они относились к системе координат извлеченного изображения, а не к системе координат исходного изображения.

Замените все r и c на 2 и 2, все r-1 и c-1 на 1 и 1 и, наконец, все r+1 и c+1 на 3 и 3. Что касается точности вашего алгоритма, это должны быть единственные исправления, которые вам нужны, и если я правильно понимаю ваше описание, это должно более или менее дать вам то, что вы хотите. Однако есть несколько подозрительных переменных, к которым осуществляется доступ, но они не определены в вашем скрипте. Такими переменными являются out, output и temp. Я принимаю их на веру и предполагаю, что вы объявили их перед этим кодом. Есть более векторизованные подходы к выполнению того, что вы хотите, но я оставлю это в качестве упражнения.

В частности, изменить:

   g0 = double(img_temp(r-1,c) - img_temp(r,c));
   g1 = double(img_temp(r, c-1) - img_temp(r,c));
   g2 = double(img_temp(r, c+1) - img_temp(r,c));

To:

   g0 = double(img_temp(1,2) - img_temp(2,2));
   g1 = double(img_temp(2, 1) - img_temp(2,2));
   g2 = double(img_temp(2, 3) - img_temp(2,2));

Изменять:

 g0 = double(img_temp(r,c+1) - img_temp(r,c));
 g1 = double(img_temp(r-1,c) - img_temp(r,c));
 g2 = double(img_temp(r+1 ,c) - img_temp(r,c));

To:

 g0 = double(img_temp(2,3) - img_temp(2,2));
 g1 = double(img_temp(1,2) - img_temp(2,2));
 g2 = double(img_temp(3 ,2) - img_temp(2,2));

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

person rayryeng    schedule 23.05.2016
comment
Попробуйте это и дайте мне знать! - person rayryeng; 23.05.2016
comment
Да. Но мне тоже пришлось внести пару изменений в свой код. - person Shin; 24.05.2016
comment
@Shin Я принял ваш код за чистую монету, поэтому я не знал, какие еще изменения вы должны были внести. Кем они были? - person rayryeng; 24.05.2016