2013-06-24 1 views
0

Предположим, что у меня есть матрица изображений RGB, и я хочу применить к ней некоторые пространственные фильтры. В общем, я хочу применить элементарные операции (обратите внимание, что это назначение в колледже, и мне не разрешено использовать какие-либо встроенные функции, доступные в панели инструментов Image Processing). Я решил написать фильтры как функции, а затем применить bsxfun к этим функциям на изображении.Как применять элементарные операции без использования для циклов и без влияния на скорость

Простой пример был бы этим:
Я хочу, чтобы добавить 50 все уровни серых изображения, а затем заменить все уровни серых с выше 200 с 200. Вот мой код:

a='C:\Users\sepideh\Desktop\IP_abadpour\S45C-113050518040.jpg'; 
b=imread(a); 
b(:,:,1)=b(:,:,1)+50; 
b(:,:,2)=b(:,:,2)+50; 
b(:,:,3)=b(:,:,3)+50; 
c=reshape(b,[],1); 
d=bsxfun(@test,c,200); 

test является функция в таком виде:

function Out = test(in,a) 
    if in>a 
     in=200; 
    end 
    Out = in; 
end 

Этот код не будет работать, потому что во второй строке «в> а» матрица, имеющая 0 и 1. (я имею в виду все элементы не 1 и не должны быть), поэтому отладчик не будет входить в th e if заявление.

Не могли бы вы посоветовать мне, как писать эту функцию и как применять пространственный и четкий анализ изображения, не влияя на производительность и скорость выполнения?

ответ

1

Вот несколько советов:

  1. Прежде всего, вам не нужно добавить 50 к каждому слою матрицы RGB индивидуально. Вы можете просто сделать:

    b = b + 50; 
    
  2. Почему вы перекроить b перед передачей его в bsxfun? Размер вывода bsxfun такой же, как у вашего изображения, в этом нет необходимости переделывать что-либо.

  3. Что касается вашего test функции, обратите внимание, что в official documentation of bsxfun состояния:

    Двоичный поэлементно функция вида C = fun(A,B) принимает массивы A и B произвольной, но одинакового размера и возвращает вывод одного и того же размера. Каждый элемент в выходном массиве C является результатом операции над соответствующими элементами только A и B. fun также должен поддерживать скалярное расширение, так что если A или B является скаляром, то C является результатом применения скаляра к каждому элементу другого входного массива.

    Так bsxfun выполняет одноэлементное расширение и «раздувают» своих два входных массивы одинакового размера, а затем применяет указанную функцию завышенных массивов. Элементная функция fun работает, по сути, на массивах, а не на скалярах. Я не вижу никакого фактического выигрыша в использовании bsxfun здесь.

    Тем не менее, вы можете упростить код, как показано в Dan «предложение s, или реализовать его как функцию:

    function out = test(in, a); 
        out = in; 
        out(in > a) = a; 
    

    Я полагаю, что если вы использовали значение 210 вместо 200, вы» хотели бы ограничить все уровни серых с 210, а также, так что вы действительно должны использовать a вместо жестко предопределенного значения 200. вы также можете написать функцию следующим образом:

    function out = test(in, a) 
        out = min(in, a); 
    

    и затем вызвать его:

    d = test(b, 200); 
    

    вместо более сложных d = bsxfun(@test, b, 200).

    Другой альтернативой является использование arrayfun: в котором будет применяться

    d = arrayfun(@(x)test(x, 200), a); 
    

    или

    d = arrayfun(@test, a, 200 * ones(size(a))); 
    

    arrayfuntest поэлементно, а функция test нужно будет работать только на скаляры. Однако arrayfun обычно работает медленнее, чем циклы, не говоря уже о векторизованных операциях.

  4. Для пространственного анализа ознакомьтесь с conv2 точно так же, как Dan предложил (или применил свою собственную 2-мерную свертку, для практики). Для анализа Фурье рассмотрите функции fft2 и ifft2 в частотной области.

Надеюсь, это поможет!

+0

Хорошо, что функция, которую вы предложили, работает хорошо, за исключением того, что функция max должна быть заменена на min.But еще один вопрос поднялся. Почему моя функция не работает. Я имею в виду, что если вы остановите отладчик в funtion, вы увидите, что «in» не является скаляром и является матрицей при вызове теста, и вы сказали: нет ничего плохого в вашей функции, поскольку она в настоящее время написана ?? !!! !! – sepideh

+0

@sepideh О, ты прав, мой плохой! См. Мое редактирование. –

1

Так для примера вы вывесили вы можете просто воспользоваться тем фактом, что большинство операторов в MatLab работе над матрицами нативно:

b=imread(a); 
c = a + 50; 
c(c > 200) = 200; 

Это так просто.

Для фильтрации, если вам разрешено, я бы посмотрел на функцию conv2. Вы можете сделать пространственную фильтрацию таким образом, не превращаясь в частотную область (помните, умножение фильтра в частотной области такое же, как свертка в пространственной области). Так, например, основной фильтр низких частот:

lpf = ones(5)./25; 
c(:,:,1) = conv2(b(:,:,1), lpf); 
c(:,:,2) = conv2(b(:,:,2), lpf); 
c(:,:,3) = conv2(b(:,:,3), lpf);