2016-06-21 6 views
0

Пусть размер моей матрицы A равен sx x sy x sz. Я хочу получить матрицу B (с таким же размером, как A), где элемент B в (x,y,z) представляет собой среднее значение подматрицы n x n x n, извлеченной из той же позиции в A.Быстрое усреднение 3D-подматриц в Matlab

Как я могу это сделать?

Я знаю, что могу это сделать, используя convn или используя 3 for петли, но это будет очень медленно.

Матрица A размера 200 x 200 x 150 находится в double точность на моей машине, когда я использую n = 9 занимает около 20-30 секунд.

+0

'convn', скорее всего, самый быстрый способ сделать это, так что если это слишком медленно для вас, то, вероятно, нам нечего предложить. – Suever

+1

Попробуйте использовать GPU, если он доступен. Графические процессоры превосходят выполнение сверток. –

+0

Можете ли вы предоставить спецификации своей машины? Для меня это занимает в среднем около 1 секунды ... что я считаю довольно быстрым для этого относительно большого количества данных и указанного вами ядра. Это может быть просто ваша машина, которая ограничивает производительность. – rayryeng

ответ

3

Рассмотрите возможность использования imfilter из Image Processing Toolbox. imfilter представляет собой, по существу, оптимизированный трубопровод свертки и корреляции, который использует Intel Integrated Performance Primitives. Так же, как простой тест, давайте создадим случайную double точность 200 х 200 х 150 3D матрицы и мы хотим, чтобы найти среднее значение 9 х 9 х 9 пикселей окрестностей, как вы сказали:

A = rand(200,200,150); 
kernel = (1/9^3)*ones(9,9,9); 
B = imfilter(A, kernel); 

Это на самом деле работает довольно быстро на моей машине. Мои спецификации - MacBook Pro с 16 ГБ оперативной памяти, работающей на процессоре Intel Core i7 емкостью 2,3 ГГц.

Просто, чтобы удовлетворить любопытство, я timeit времени, сколько времени эта операция занимает, как только вы выделить ядро ​​и матрицу:

A = rand(200,200,150); 
kernel = (1/9^3)*ones(9,9,9); 
B = imfilter(A, kernel); 
t = timeit(@() imfilter(A, kernel)); 

В среднем, приведенный выше код работает около 1,1393 секунд:

>> t 

t = 

    1.1393 

Если вы не перейдете на графические процессоры, это для меня самый быстрый способ, которым вы когда-либо собираетесь его получить ... особенно потому, что у вас есть 150 фрагментов 200 x 200 2D-данных, которые вы должны обрабатывать с каждой точкой, собирающей 9 x 9 x 9 единиц.