Как реализовать часть выравнивания гистограммы в Matlab без использования для циклов и влияния скорости и производительности

Предположим, что у меня есть эти три переменные в MatLab переменных Я хочу извлечь различные значения в NewGrayLevels и суммировать строки OldHistogram, которые находятся в тех же строках, что и одно различное значение. Например, вы видите в NewGrayLevels, что шесть первых строк равны нулю. Это означает, что 0 в NewGrayLevels взял свое значение из (0 1 2 3 4 5) OldGrayLevels. Поэтому соответствующие строки в OldHistogram следует суммировать. Таким образом, 0 + 2 + 12 + 38 + 113 + 163 = 328 будет частотой уровня серого 0 в уравненной гистограмме и так далее. Те, кто знаком с обработкой изображений, знают, что это часть алгоритма выравнивания гистограммы. Обратите внимание, что я не хочу использовать встроенную функцию "histeq", доступную в панели инструментов обработки изображений, и я хочу ее реализовать самостоятельно. Я знаю, как написать алгоритм с циклами. Я ищу, если есть более быстрый способ, не используя для циклов. Код, используемый для циклов:

for k=0:255
 Condition = NewGrayLevels==k;
 ConditionMultiplied = Condition.*OldHistogram;
 NewHistogram(k+1,1) = sum(ConditionMultiplied);
 end

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

3 ответа

Хорошо, я понял, что нет необходимости писать код, который предложил @Hugh Nolan. См. Объяснение здесь:

%The green lines are because after writing the code, I understood that 
%there no need to calculate the equalized histogram in 
%"HistogramEqualization" function and after gaining the equalized image 
%matrix you can pass it to the "ExtractHistogram" function 
% (which there no loops in it) to acquire the 
%equalized histogram. 
%But I didn't delete those lines of code because I had tried a lot to 
%understand the algorithm and write them.

Для получения дополнительной информации и изучения кода см. Мой следующий вопрос.


Я не могу представить способ реализовать это без цикла for, но одна оптимизация, которую вы могли бы сделать, будет использовать индексирование вместо умножения:

for k=0:255
 Condition = NewGrayLevels==k; % These act as logical indices to OldHistogram
 NewHistogram(k+1,1) = sum(OldHistogram(Condition)); % Removes a vector multiplication, some additions, and an index-to-****** conversion
end

Редактировать:

Перечитывая свой начальный пост, я думаю, что способ сделать это без цикла for - использовать накопитель (я считаю, что это трудная функция для понимания, поэтому читайте документацию и выполните поиск в Интернете и здесь, чтобы привести примеры):

NewHistogram = accumarray(1+NewGrayLevels,OldHistogram);

Это должно работать до тех пор, пока ваше максимальное значение в NewGrayLevels (+1, потому что вы начинаете с нуля) равно длине OldHistogram.


Я знаю, что вы говорите, что не хотите использовать histeq, но, возможно, стоит потратить время на исходный файл MATLAB, чтобы посмотреть, как разработчики его написали, и скопировать части своего кода, которые вы хотели бы реализовать. Просто измените ("histeq") или отредактируйте ("histeq.m"), я забыл, что.

Обычно код MATLAB векторизован, где это возможно, и работает довольно быстро. Это может спасти вас от необходимости изобретать все колесо, просто части, которые вы хотите изменить.

licensed under cc by-sa 3.0 with attribution.