+1 к @Floris за отличное предложение использовать hist
. Это очень быстро. Вы можете сделать немного лучше, хотя. hist
основан на histc
, который может использоваться вместо этого. histc
является скомпилированной функцией, то есть не написанной в Matlab, поэтому решение выполняется намного быстрее.
Вот небольшая функция, которая пытается обобщить то, что сделал @Floris (также это решение возвращает вектор, а не желаемую матрицу) и добивается того, что вы делаете с nlfilter
и colfilt
. Он не требует, чтобы вход имел конкретные размеры и использует im2col
для эффективной переупорядочивания данных. Фактически, первые три строки и вызов im2col
практически идентичны тому, что делает colfit
в вашем случае.
function a=intmodefilt(a,nhood)
[ma,na] = size(a);
aa(ma+nhood(1)-1,na+nhood(2)-1) = 0;
aa(floor((nhood(1)-1)/2)+(1:ma),floor((nhood(2)-1)/2)+(1:na)) = a;
[~,a(:)] = max(histc(im2col(aa,nhood,'sliding'),min(a(:))-1:max(a(:))));
a = a-1;
Использование:
x = randi(5,10,10);
y3 = intmodefilt(x,[3 3]);
Для больших массивов, это более 75 раз быстрее, чем colfilt
на моей машине. Замена hist
на histc
несет ответственность за коэффициент ускорения. Там нет, конечно, не проверяя таким образом вход функция предполагает, что a
это все целые числа, и т.д.
Наконец, отметим, что randi(IMAX,N,N)
возвращает значения в диапазоне 1:IMAX
, не 0:IMAX
, как вы, кажется, состояние.
Фильтр режима всегда будет медленным, так как он должен гистограммировать значения, а затем искать наиболее распространенное значение - так что вы получите несколько проходов через наши данные. Реализован в «ванильном матлабе», который очень медленный. Вы можете быть намного быстрее, написав для себя небольшую рутину «mex» - с этим легко справиться. Вам нужны какие-то указатели? – Floris
Хм ... Я никогда не писал рутину mex ... Знаете ли вы простой пример, который я могу взять в качестве образца? Мне было бы легче начать. – user2441536