2012-03-26 17 views
0

は、私が式を使用していますniblackしきい値処理アルゴリズムを実装しようとしています:kは標準値0 を有する場合niblackのしきい値

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

誰かがMATLABでこれを実装する方法を教えていただけますか?私は、あなたが全体の画像を処理することができ、それを

答えて

4

: は、あなたが3つの行列を持っていると仮定すると、 1つの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

ローカル標準のイメージはありますか?私はあなたが提供したグレースケールイメージでJavaで行われた自分の実装をテストしようとしましたが、結果はまったく異なります。私たちの標準は平均と同じように見えますか? – user2700896

0

を行う方法を見つけ出すカント:Matlabのの電源が行列演算であるので、あなたが行うことができますimg_in、オブジェクト、背景

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

標準偏差の計算方法は? – NeedHelp

+0

あなたの説明から、あなたがしようとしていることは非常に不明です。あなたの入力と希望する出力を指定してください。 – Serg

+0

私はドキュメントイメージを取って、それをグレースケールに変換した後、このしきい値アルゴリズムを実装しようとします。しかし、私は個々のピクセルに個々にそれを実装する方法を知らないので、最終的な結果はテキストが背景から分離された二値化されたイメージになります。 – NeedHelp

2

私はそれがNiblackアルゴリズムではなく、より良い結果を与える実装ではありません先行言いたいです。この実装がどこで失敗するのか分かりませんが、上記の画像を2進化しようとしましたが、その結果は以下のようになります。

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

大きな画像をブロックに分割するコードも含めることは非常に便利です。あなたはそれを追加できますか? –

+0

[リンク](https://github.com/tilaprimera/scanned_images_binarization/blob/master/helper_function.py)は画像を分割するimg_divide関数を参照してください。それは効率的なコードではない、私は追加する必要があります。 – tilaprimera

関連する問題