ниблачный порог

Я пытаюсь реализовать алгоритм определения порога niblack, который использует формулу:

pixel = ( pixel >  mean + k * standard_deviation ) ? object : background

где k имеет стандартное значение 0. Может ли кто-нибудь сказать мне, как реализовать это в Matlab? Я не могу понять, как это сделать

Ответы на вопрос(3)

при условии, что у вас есть три матрицы: img_in, object, background

flag = img_in >  mean + k * standard_deviation;
img_out = flag .* object + (1 - flag) .* background;
 Serg26 мар. 2012 г., 17:42
Из вашего описания очень неясно, что вы собираетесь делать. Пожалуйста, укажите ваш вход и желаемый выход.
 NeedHelp26 мар. 2012 г., 17:25
Как рассчитать стандартное отклонение ???
 NeedHelp26 мар. 2012 г., 20:45
Я беру изображение документа и после преобразования его в оттенки серого я пытаюсь реализовать этот алгоритм порогового значения. Но я не знаю, как реализовать его для каждого пикселя в отдельности, поэтому конечным результатом является бинаризованное изображение, в котором текст отделяется от фона. Не могли бы вы сказать мне, как это сделать?
Решение Вопроса

поэтому вы можете многое сделать без единого цикла for. Код ниже делает то, что вам нужно.

% define parameters
imgname = 'rice.png'; % matlab's image
filt_radius = 25; % filter radius [pixels]
k_threshold = 0.2; % std threshold parameter
%% load the image
X = double(imread(imgname)); 
X = X / max(X(:)); % normalyze to [0, 1] range
%% build filter
fgrid = -filt_radius : filt_radius;
[x, y] = meshgrid(fgrid);
filt = sqrt(x .^ 2 + y .^ 2) <= filt_radius;
filt = filt / sum(filt(:));
%% calculate mean, and std
local_mean = imfilter(X, filt, 'symmetric');
local_std = sqrt(imfilter(X .^ 2, filt, 'symmetric'));
%% calculate binary image
X_bin = X >= (local_mean + k_threshold * local_std);
%% plot
figure; ax = zeros(4,1);
ax(1) = subplot(2,2,1); imshow(X); title('original image');
ax(2) = subplot(2,2,2); imshow(X_bin); title('binary image');
ax(3) = subplot(2,2,3); imshow(local_mean); title('local mean');
ax(4) = subplot(2,2,4); imshow(local_std); title('local std');
linkaxes(ax, 'xy');

 user270089624 мар. 2017 г., 01:22
Ты уверен насчет имиджа для местного стандарта? Я попытался протестировать мою собственную реализацию, выполненную на Java, с предоставленным вами изображением в градациях серого, и результаты оказались совершенно другими. Похоже, наш стандарт является таким же, как в среднем?

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

Я разделил изображение на блок 25 * 25 пикселей, а затем использовал глобальное среднее значение 90 и глобальное среднее значение 20. Затем применил бинаризацию Оцу к маленьким окнам.

set_mean = 90
set_sd = 20
mean_block = np.mean(block)
sd_block = np.std(block)
if sd_block > set_sd:
    ret, block = cv2.threshold(block, 0, 255, cv2.THRESH_OTSU)
elif sd_block < set_sd:
    if mean_block > set_mean:
        block[:] = 255 #white
    else:
        block[:] = 0 #black
return block

Если стандартное отклонение (SD) небольшого окна больше установленного, то используется пороговое значение отсу, в зависимости от того, больше или меньше среднее значение, чем установленное среднее, пиксели в окне устанавливаются как черные или белые.

 Zoran Pavlovic28 сент. 2014 г., 18:39
Было бы очень удобно также включить код, который разбивает увеличенное изображение на блоки. Можно ли добавить это, пожалуйста?
 tilaprimera29 сент. 2014 г., 16:18
Вотссылка см. функцию img_divide для разделения изображения вверх. Это не эффективный код, я должен добавить.

Ваш ответ на вопрос