一:大津阈值及其变种
该方法的核心就是计算背景和前景的最大类间方差,把类间方差最大的像素值作为全局二值化的阈值,计算费时。全局阈值,要根据适用场景选择性的应用。
变种:在[0 T] 内继续寻找ostu值, 在[T 255]内继续寻找ostu值。
- clear;
- close all;
- clc;
- G = imread('input.JPG');
- I = rgb2gray(G);
- [m,n] = size(I);
- Hist = zeros(255);
- dHist = zeros(255);
- variance = zeros(255);
- PXD = 0;
- for i = 1:m
- for j = 1:n
- Hist(uint8(I(i,j))) = Hist(uint8(I(i,j))) + 1;
- end
- end
- for i = 1:255
- dHist(i) = Hist(i)/(m*n);
- end
- for PXD = 1:255
- w0 = 0;
- w1 = 0;
- g0 = 0;
- g1 = 0;
- for i = 1:PXD
- g0 = g0 + i*dHist(i);
- w0 = w0 + dHist(i);
- end
- for i = PXD+1 : 255
- g1 = g1 + i*dHist(i);
- w1 = w1 + dHist(i);
- end
- variance(PXD) = w0*w1*(g0 - g1)*(g0 - g1);
- end
- PXD = 1;
- for i = 1:255
- if variance(PXD) < variance(i)
- PXD = i;
- end
- end
- for i = 1:m
- for j = 1:n
- if I(i,j) > PXD
- I(i,j) = 255;
- else
- I(i,j) = 0;
- end
- end
- end
- imagBW = I
二:Bernsen算法实现图像二值化,该方法属于局部方法
- clc;
- clear;
- close all;
- I = imread('input.bmp');
- w = 1;
- T = 0;
- max = 0;
- min = 0;
- [m,n] = size(I);
- T = zeros(m - 2*w,n - 2*w);
- for i = (w + 1):(m - w)
- for j = (w + 1):(n - w)
- max = uint8(I(i,j));
- min = uint8(I(i,j));
- for k = -w:w
- for l = -w:w
- if max < uint8(I(i + k,j + l))
- max = uint8(I(i + k,j + l));
- end
- if min > uint8(I(i + k,j + l))
- min = uint8(I(i + k,j + l));
- end
- end
- end
- T(i,j) = 0.5*(max + min);
- end
- end
- for i = (w + 1):(m - w)
- for j = (w + 1):(n - w)
- if I(i,j) > T(i,j)
- I(i,j) = uint8(255);
- else
- I(i,j) = uint8(0);
- end
- end
- end
- imshow(I);
三:Niblack 二值化
该方法仍然是一种二值化方法,阈值的计算公式是T = local_avg + k*v,其中local_avg表示以该像素点为中心的区域的平均灰度值,v是该区域的标准差,k是一个可以调节的系数
- clc;
- clear;
- close all;
- I = imread('input.bmp');
- I = rgb2gray(I);
- w = 2;
- max = 0;
- min = 0;
- [m,n] = size(I);
- T = zeros(m ,n );
- for i = (w + 1):(m - w)
- for j = (w + 1):(n - w)
- sum = 0;
- for k = -w:w
- for l = -w:w
- sum = sum + uint32(I(i + k,j + l));
- end
- end
- average = double(sum) /((2*w+1)*(2*w+1));
- s = 0;
- for k = -w:w
- for l = -w:w
- s = s + (uint32(I(i + k,j + l)) - average)*(uint32(I(i + k,j + l)) - average);
- end
- end
- s= sqrt(double(s)/((2*w+1)*(2*w+1)));
- T(i,j) = average + 0.2*s;
- end
- end
- for i = 1:m
- for j = 1:n
- if I(i,j) > T(i,j)
- I(i,j) = uint8(255);
- else
- I(i,j) = uint8(0);
- end
- end
- end
- imshow(I);
四:局部block分析二值化方法
Block Analysis大体思想是基于Niblack算法的,只不过把图像进行分块,然后对每一块计算阈值,T = local_avg + k*v,其中local_avg表示以该像素点为中心的区域的平均灰度值,v是该区域的标准差,k是一个可以调节的系数
- clc;
- clear;
- close all;
- I = imread('100_1243.JPG');
- I = rgb2gray(I);
- [m,n] = size(I);
- block = 10;
- ver = floor(m/block);
- hor = floor(n/block);
- T = zeros(m,n);
- for b_ver = 1:block
- for b_hor = 1: block
- t = 0;
- for i = (ver * (b_ver - 1)+1) : (ver * b_ver)
- for j = (hor * (b_hor - 1) + 1):(hor * b_hor)
- t = t + uint32(I(i,j));
- end
- end
- t = double(t)/(ver * hor);
- std_deviation = 0;
- for i = (ver * (b_ver - 1)+1) : (ver * b_ver)
- for j = (hor * (b_hor - 1) + 1):(hor * b_hor)
- std_deviation = std_deviation + (uint32(I(i,j)) - t)*(uint32(I(i,j)) - t);
- end
- end
- std_deviation = sqrt(double(std_deviation)/(ver*hor));
- thr = t + 0.2*std_deviation;
- for i = (ver * (b_ver - 1)+1) : (ver * b_ver)
- for j = (hor * (b_hor - 1) + 1):(hor * b_hor)
- if I(i,j) > uint8(floor(thr))
- T(i,j) = 255;
- else
- T(i,j) = 0;
- end
- end
- end
- end
- end
- imshow(T);
五:sauvola二值化算法
将图像分块,每块内的均值为local_avg. 阈值T=local_avg*(1+k*(s/R-1)) 其中k为可以调节的阈值,常取0.5,s为局部像素和均值的标准差,s=(pix_val - local_avg)^2/block_pixel_count. R = 128. 该方法在保留图像细节方面有很强的效果。