我已经在Matlab中实现了Niblack的算法。然而,我取得了一些值得怀疑的结果。
我下载了一些测试图像,尝试对其执行一些文档二值化。但是,我不确定它们看起来是否正确。下面是图像和我的代码,我尝试通过执行各种功能来使其模块化。谢谢!
将 k 等级提升至 2 结果:
我的代码
% K value
k_threshold = -0.1;
%input image
image1 = imread('test1.jpg');
%convert to grayscale
image1 = rgb2gray(image1);
%convert to double
image1 = double(image1);
% normalise to [0,1] range
image1 = image1 / max(image1(:));
%mean filtering
mean = averagefilter2(image1);
%standard deviation
standardDeviation = standardDev(image1, mean);
%calculate binary image
binaryImage = image1 >= (mean + k_threshold * standardDeviation);
%display image
display = displayImage(binaryImage, image1);
function deviation = standardDev(image1, mean)
meanSquare = averagefilter2(image1.^2);
deviation = (meanSquare - mean.^2).^0.5;
end
function [X,Y] = displayImage (binaryImage, image1)
close;
figure;
X = imshow(image1); title('original image');
figure;
Y = imshow(binaryImage); title('binary image');
end
function img=averagefilter2(image1)
meanFilter = fspecial('average',[3 3]);
img = imfilter (image1,meanFilter);
end
Niblack 阈值算法将阈值设置为
T(i, j) = m(i, j) + ϵ * s(i, j)
,其中 m(i, j)
是 (i, j)
邻域的平均值,s(i, j)
是 (i, j)
处的标准差。参数 ϵ
由用户控制。
这会生成
T(i, j)
,它是 (i, j)
处特定像素的阈值。
给定快速卷积引擎,计算此值的简单方法是利用恒等式:
var(x) = E[x^2] - (E[x])^2
。
所以步骤是:
ϵ
的参数。Julia 实现:
function ApplyNiblackThr( mI :: Matrix{T}, boxRadius :: N, ϵ :: T ) where {T <: AbstractFloat, N <: Integer}
# Quantized image colors using K-Means.
# Local Mean
mM = ApplyBoxBlur(mI, boxRadius; padMode = PAD_MODE_REFLECT);
# Local Variance
# Based on: Var(x) = E[(x - μ)^2] = E[x^2] - E[x]^2
mS = sqrt.(max.(ApplyBoxBlur(mI .* mI, boxRadius; padMode = PAD_MODE_REFLECT) .- (mM .* mM), zero(T)));
return mI .> mM .+ ϵ .* mS; #<! Thresholding
end
代码可以在我的 StackOverflow GitHub Repository 上找到(查看
StackOverflow\Q20331314
文件夹)。