二值法方法综述及matlab程序
在某些图像处理当中一个关键步是二值法,二值化一方面能够去除冗余信息,另一方面也会使有效信息丢失。所以有效的二值化算法是后续的处理的基础。比如对于想要最大限度的保留下面图的中文字,以便后续的定位处理。 二值化算法包括全局二值化和局部二值化, 全局二值化具有速度快但效果相对差的特点, 局部二值化算法具有速度慢效果好的特点。
原图
全局阈值
方法一:直接采用im2bw ;手动阈值
方法二:迭代法求阈值
迭代式阈值选取的基本思路是:首先根据图像中物体的灰度分布情况,选取一个近似阈值作为初始阈值,一个较好的方法就是将图像的灰度均值作为初始阈值;然后通过分割图像和修改阈值的迭代过程获得认可的最佳阈值。迭代式阈值选取过程可描述如下。
(1)选取一个初始阈值T。
(2)利用阈值T把给定图像分割成两组图像,记为R1和R2 。
(3)计算R1和R2 均值u1和 u2
(4)选取新的阈值T,且T=(u1+u2)/2
(5)重复第(2)~(4)步,直至R1和R2均值不再变化为止。
具体实现时,首先根据初始开关函数将输入图逐个图像分为前景和背景,在第一遍对图像扫描结束后,平均两个积分器的值以确定一个阈值。用这个阈值控制开关再次将输入图分为前景和背景,并用做新的开关函数。如此反复迭带直到开关函数不在发生变化,此时得到的前景和背景即为最终分割结果。迭代所得的阈值分割的图像效果良好。基于迭代的阈值能区分出图像的前景和背景的主要区域所在,但在图像的细微处还没有很好的区分度。对某些特定图像,微小数据的变化却会引起分割效果的巨大改变,两者的数据只是稍有变化,但分割效果却反差极大。对于直方图双峰明显,谷底较深的图像,迭代方法可以较快地获得满意结果,但是对于直方图双峰不明显,或图像目标和背景比例差异悬殊,迭代法所选取的阈值不如其它方法。将全局平均值作为初始阈值,将图像分为两部分,求每部分的均值,迭代,直到这两部分均值不在变化。
function [b1 ] = binary_iterate( f1 )
% 用迭代的方法对图像进行二值化 t=mean(f1(:));
is_done=false;
count=;
while ~is_done r1=f1(f1<=t);
r2=f1(f1>t);
temp1=mean(r1(:));
if isnan(temp1);
temp1=;
end
temp2=mean(r2(:));
if isnan(temp2)
temp2=;
end
t_new=(temp1+temp2)/;
is_done=abs(t_new-t)<;
t=t_new;
count=count+;
if count>=
Error='Error:Cannot find the ideal threshold.'
Return
end
end b1=im2bw(mat2gray(f1),t/);
end
方法三:居于最大类间差的方法----Otsu法
图像记t为前景与背景的分割阈值,前景点数占图像比例为w0,平均灰度为u0;背景点数占图像比例为w1,平均灰度为u1,则图像的总平均灰度为:u=w0*u0+w1*u1从最小灰度值到最大灰度值遍历t,当t使得值g=w0*(u0-u)^2+w1*(u1-u)^2最大时t即为分割的最佳阈值。
大津法可作如下理解:该式实际上就是类间方差值,阈值t 分割出的前景和背景两部分构成了整幅图像,而前景取值u0,概率为 w0,背景取值u1,概率为w1 ,总均值为u,根据方差的定义即得该式。因方差是灰度分布均匀性的一种度量,方差值越大,说明构成图像的两部分差别越大,当部分目标错分为背景或部分背景错分为目标都会导致两部分差别变小,因此使类间方差最大的分割意味着错分概率最小。直接应用大津法计算量较大,因此在实现时采用了等价的公式g=w0*w1*(u0-u1)^2第二,第三种方法得到的阈值相差不大,效果也类似,不能解决光照不均的局面。这是因为用全局阈值是无法根据每个特定的区域采用不同的阈值,于是只能尝试采用局部阈值,或是对图像进行预处理改进其直方图特性。
function [b1,reT] =binary_otus( f1 )
% otus法二值化
[r c]=size(f1);
gray_level=;
resultT=;
hist=zeros(gray_level,);
for i=:r
for j=:c
hist(f1(i,j)+)=hist(f1(i,j)+)+;
end
end
hist=hist/(r*c);
vmax=;
for tt=:gray_level
T=tt-;
w0=;w1=;u0=;u1=;var=;%重要的地方,在每次循环遍历的时候。要把涉及到的变量清零。
for i=:T+
w0=w0+hist(i);
u0=u0+(i-)*hist(i);
end
u0=u0/w0;
w1=-w0;
for j=T+:gray_level
u1=u1+(j-)*hist(j);
end
u1=u1/w1;
var=w0*w1*(u0-u1)^;
% v(tt)=var;
if var>vmax
vmax=var;
resultT=T;
end
end
b1=im2bw(mat2gray(f1),resultT/);
reT=resultT/;
end
局部阈值法
方法四:分块otus
对图像分块,对每块采用方法三最大类间差的方法处理,(改进的地方分块的长宽不是一致的)设置的窗口为10*10.。 看上图,明显看到光照不均那段被检测出来 了,但是缺点是要很好的设置好分块的大小。而且图片产生了伪影,多出了很多黑块。怎么会出现这些黑块呢?观察后发现黑块往往是在图像灰度细节不够丰富的区域产生。黑块产生的原因一定是出在每个分块采用的二值化方法--otsu算法。otsu算法更适合空间细节不丰富但灰度细节却很丰富的图像,因为这种图像往往才会有明显的类间距。对于灰度不丰富的图像,otsu 得到的阈值较不理想。
function [ b1] = binary_part(gray_image,a,b)
% 采用局部二值化,各个局部采用otus法
[m,n]=size(gray_image);
result=zeros(m,n);
for i=:a:m
for j=:b:n
if ((i+a)>m)&&((j+b)>n) %分块
block1=gray_image(i:end,j:end); %右下角区块
elseif ((i+a)>m)&&((j+b)<=n)
block1=gray_image(i:end,j:j+b-); %最右列区块
elseif ((i+a)<=m)&&((j+b)>n)
block1=gray_image(i:i+a-,j:end); %最下行区块
else
block1=gray_image(i:i+a-,j:j+b-); %普通区块
end [ block,~]=binary_otus(block1);
if ((i+a)>m)&&((j+b)>n) %合并结果
result(i:end,j:end)=block;
elseif ((i+a)>m)&&((j+b)<=n)
result(i:end,j:j+b-)=block;
elseif ((i+a)<=m)&&((j+b)>n)
result(i:i+a-,j:end)=block;
else
result(i:i+a-,j:j+b-)=block;
end
end
end b1=result;
end
方法五:ernsen算法
ernsen算法凭其优异的综合性能, 在局部二值化领域占有重要一席, 它较适合解决光照不均的问题。这个算法的中心思想是:设当前像素为P,计算以P为中心的大小为(2w+1)*(2w+1)窗口内的所有像素的最大值M与最小值N,两者的均值T,if(M-N)> S 则当前点P的阈值为T。else当前窗口所在区域的灰度级差别较小,那么窗口在目标区或在背景区,若T>T1则当前点灰度值为255,否则,当前点灰度值为0。S设为15, T1设为20。(这两个值的设定还是需要根据具体的图像具体分析)从上图中可以看到bernsen方法能够较为有效的解决光照不均的问题。美中不足的是这方法运行的时间太长,针对这一问题也有很多的改善的方法。
function [ b1 ] = binary_bernsen( f1 )
% 局部二值化方法,局部区域采用简单阈值。
[m,n]=size(f1);
s=;
t1=;
exI=uint8(ones(m+,n+));%扩展图片,预分配一个矩阵
re=uint8(ones(m,n));
exI(:m+,:n+)=f1;%把原图片赋给矩阵
%==========对矩阵进行填充==========%
exI(,:)=exI(,:);
exI(m+,:)=exI(m+,:);
exI(:,)=exI(:,);
exI(:,n+)=exI(:,n+); for i=:m+
for j=:n+
%===========求3*3区域内的阈值并对图像进行二值化,结果存在re中==========%
ma=max(max(exI(i-:i+,j-:j+)));
mi=min(min(exI(i-:i+,j-:j+)));
t=(ma+mi)/;
if ma-mi>s
if exI(i,j)>t
re(i-,j-)=;
else
re(i-,j-)=;
end
else
if t>t1
re(i-,j-)=;
else
re(i-,j-)=;
end
end end
end b1=re;
end
主函数:
clc;
clear all;
[fn pn fi]=uigetfile('*.*','choose a picture');
Img=imread([pn fn]);
Img_gray=rgb2gray(Img);
Img_bw=binary_bernsen(Img_gray);%这里修改对应的函数
figure;
imshow(Img_bw);
imwrite(Img_bw,'bw.jpg')
二值法方法综述及matlab程序的更多相关文章
- 二值化方法:Kittler:Minimum Error Thresholding
Kittler二值化方法,是一种经典的基于直方图的二值化方法.由J. Kittler在1986年发表的论文“Minimum Error Thresholding”提出.论文是对贝叶斯最小错误阈值的准则 ...
- python实现超大图像的二值化方法
一,分块处理超大图像的二值化问题 (1) 全局阈值处理 (2) 局部阈值 二,空白区域过滤 三,先缩放进行二值化,然后还原大小 np.mean() 返回数组元素的平均值 np.std() 返回数 ...
- [python-opencv]超大图像二值化方法
*分块 *全局阈值 VS 局部阈值 import cv2 as cv import numpy as np def big_image_binary(image): print(image.shape ...
- 一种局部二值化算法:Sauvola算法
之前接触过全局二值化(OTSU算法),还有OPENCV提供的自适应二值化,最近又了解到一种新的局部二值化算法,Sauvola算法. 转载自:http://www.dididongdong.com/ar ...
- 二值化函数cvThreshold()参数CV_THRESH_OTSU的疑惑【转】
查看OpenCV文档cvThreshold(),在二值化函数cvThreshold(const CvArr* src, CvArr* dst, double threshold, double max ...
- [python-opencv]图像二值化【图像阈值】
图像二值化[图像阈值]简介: 如果灰度图像的像素值大于阈值,则为其分配一个值(可以是白色255),否则为其分配另一个值(可以是黑色0) 图像二值化就是将灰度图像上的像素值设置为0或255,也就是将整个 ...
- atitit.验证码识别step4--------图形二值化 灰度化
atitit.验证码识别step4--------图形二值化 灰度化 1. 常见二值化的方法原理总结 1 1.1. 方法一:该方法非常简单,对RGB彩色图像灰度化以后,扫描图像的每个像素值,值小于12 ...
- openCV_java 图像二值化
较为常用的图像二值化方法有:1)全局固定阈值:2)局部自适应阈值:3)OTSU等. 局部自适应阈值则是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值.这样做的好处在于每个像素位置处的二值化 ...
- OpenCV_基于局部自适应阈值的图像二值化
在图像处理应用中二值化操作是一个很常用的处理方式,例如零器件图片的处理.文本图片和验证码图片中字符的提取.车牌识别中的字符分割,以及视频图像中的运动目标检测中的前景分割,等等. 较为常用的图像二值化方 ...
随机推荐
- svn:database disk image is malformed问题解决方法
今天一客户使用我们软件时突然停电,再次启动软件查询SQLite数据库报 The database disk image is malformed 错误. 百度一下基本上全部是http://www.cn ...
- CI框架基本配置/教你学习CI框架codelgniter
CI框架现在中国可以说还是不成熟,不像thinkphp那样有那么多的中文手册,在国内,很多国人英语都很烂,CI现在教程还是不多.大家心里都存在这严重想法 CI 框架现在中国可以说还是不成熟,不像thi ...
- 创建Spring Boot项目的几种方式总结
一.我们可以使用Spring Initializr来创建SpringBoot项目. Spring Initializr从本质上来说就是一个Web应用程序,它能为你生成Spring Boot项目结构.虽 ...
- Mybatis在IDEA中使用generator逆向工程生成pojo,mapper
使用mybatis可以逆向生成pojo和mapper文件有很多种方式,我以前用的是mybtais自带的generator包来生成,连接如下:mybatis自己生成pojo 今天我用了IDEA上使用ma ...
- postgresql on centos (sequelize+pg+nodejs):Failed to find PostgresSQL server.Pleast double check your settings
公司的一个项目,使用的nodejs做服务端,数据库是postgresql,在本地时一切ok,放在centos时,postgresql配置ok,可以远程访问,但是nodejs在centos启动时,就会报 ...
- CMake 简介与使用
cross platform make的缩写. 是一个比make更高级的编译配置工具,它可以根据不同平台.不同的编译器,生成相应的Makefile或者vcproj项目文件.通过编写CMakeLists ...
- 巧用批处理cmd快速切换IP地址
如果你的笔记本经常在不同的地方使用,有些地方需要自动获取IP,而有些地方需要配置固定IP,每换一个地方都需要重新配置一遍,是不是感觉很麻烦呢? 下面介绍一种通过建立批处理文件来快速切换IP的方法: s ...
- jxta 2.8x启动了
http://chaupal.github.io/ ———————————————————————————————————————————————————————————————————— 至少两个月 ...
- SVN如何新建用户并分配权限
打开SVN服务端,找到特定的项目目录,单击右键,然后点击属性: 在弹出的页面中,点击增加: 在增加的页面中,你可以选择之前已经创建的用户,也可以重新创建用户名和密码: 如果是选择已经有的用 ...
- Ubuntu下创建JerBrains系列软件的快捷方式
以pycharm为例: 终端输入:sudo gedit /usr/share/applications/Pycharm.desktop模板: [Desktop Entry]Type=Applicati ...