Недавно я работал над очень похожей проблемой, пытаясь вычислить порог, чтобы исключить зашумленные фоновые пиксели из данных МРТ перед выполнением других вычислений на изображениях. То, что я сделал, это подогнал сплайн к гистограмме, чтобы сгладить его, сохраняя при этом точную форму фигуры. Для подгонки я использовал пакет splinefit из обмена файлами. Я вычислил гистограмму для стека изображений, обработанных вместе, но он должен работать аналогично для отдельного изображения. Мне также довелось использовать логарифмическое преобразование данных моей гистограммы, но это может или не может быть полезным шагом для вашего приложения.
[my_histogram, xvals] = hist(reshape(image_volume), 1, []), number_of_bins);
my_log_hist = log(my_histogram);
my_log_hist(~isfinite(my_log_hist)) = 0; % Get rid of NaN values that arise from empty bins (log of zero = NaN)
figure(1), plot(xvals, my_log_hist, 'b');
hold on
breaks = linspace(0, max_pixel_intensity, numberofbreaks);
xx = linspace(0, max_pixel_intensity, max_pixel_intensity+1);
pp = splinefit(xvals, my_log_hist, breaks, 'r');
plot(xx, ppval(pp, xx), 'r');
Обратите внимание, что сплайн дифференцируем, и вы можете использовать ppdiff для получения производной, что полезно для поиска максимумов и минимумов, чтобы помочь выбрать подходящий порог. numberofbreaks
установлен на относительно низкое число, поэтому сплайн сгладит гистограмму. Я использовал linspace в примере, чтобы выбрать разрывы, но если вы знаете, что некоторая часть гистограммы демонстрирует гораздо большую кривизну, чем где-либо, вам нужно иметь больше разрывов в этом регионе и меньше в другом месте, чтобы точно отразить форму гистограмма.