2012-03-26 65 views
0

我想实现它使用公式niblack阈值算法:niblack阈值

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

其中k具有标准值0 可能有人请告诉我如何实现这在MATLAB?我无法弄清楚如何做到这一点

回答

4

Matlab的的力量是矩阵运算,所以你可以做很多没有一个单一的for-loop。 下面的代码可以满足你的需求。

% 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'); 

enter image description here

+0

你确定本地std的图像吗?我尝试用您提供的灰度图像测试我自己的Java实现,结果非常不同。它看起来像我们的标准是一样的意思? – user2700896 2017-03-24 00:22:53

0

您可以处理整个图像: 假设你有三个矩阵:IMG_IN,对象,背景

flag = img_in > mean + k * standard_deviation; 
img_out = flag .* object + (1 - flag) .* background; 
+0

我该如何计算标准偏差? – NeedHelp 2012-03-26 15:25:51

+0

从你的描述中,你打算做什么是非常不清楚的。请指定您的输入和所需的输出。 – Serg 2012-03-26 15:42:12

+0

我拿一个文件图像,并将其转换为灰度后,我尝试实现这个阈值算法。但我不知道如何实现它到每个像素单独,所以最终的结果是一个二进制图像,其中的文本从背景分离。请告诉我如何做到这一点? – NeedHelp 2012-03-26 18:45:26

2

我想说的前期是不Niblack算法,而是给出了更好的结果的实现。我不知道这个实现会失败,但我尝试对上面的图像进行二值化处理,结果如下所示。

Binarized grains

我分割图像成25×25个像素的块,然后使用20 90和全球组均值的全球集合平均,然后应用上的小窗口大津的二进制。

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)高于设定一个更大的,然后大津的阈值时,其他基于均值是否大于或小于组较小的意思是,在该窗口中的像素设置完成黑色或白色。

+0

还包括将较大图像分割成块的代码非常方便。有什么机会可以补充吗? – 2014-09-28 16:39:16

+0

这里是一个[链接](https://github.com/tilaprimera/scanned_images_binarization/blob/master/helper_function.py)看img_divide函数分割图像。这不是一个有效的代码,我必须补充。 – tilaprimera 2014-09-29 14:18:29