一、简介
1 阈值分割原理:
一副图像包括目标、背景和噪声,设定某一阈值T将图像分成两部分:大于T的像素群和小于T的像素群。
在实际处理时候,为了显示需要一般用255表示背景,用0表示对象物。
由于实际得到的图像目标和背景之间不一定单纯地分布在两个灰度范围内,此时就需要两个或以上的阈值来提取目标。
图像阈值化分割是一种传统的最常用的图像分割方法,因其实现简单、计算量小、性能较稳定而成为图像分割中最基本和应用最广泛的分割技术。它特别适用于目标和背景占据不同灰度级范围的图像。难点在于如何选择一个合适的阈值实现较好的分割。
2 最大方差阈值
最大方差阈值的基本思想是:把直方图在某一阈值处分割成两组,当被分成的的两组之间方差最大时,决定阈值。
直方图是图像的一种统计表达,由一系列高度不等的纵向条纹表示数据分布的情况。灰度直方图是灰度级的函数,它表示图象中具有每种灰度级的象素的个数,反映图象中每种灰度出现的频率( 即图像中0~255每个像素点的 个数统计)。
灰度直方图描述了图像中各种灰度(对于像素深度为 8 位的图像,共为 0-255 共256 种取值)在整个图像中占有的 比例。
如下图所示,灰度直方图的 横坐标是 灰度级, 纵坐标是该灰度级出现的 频率,是图象的最基本的统计特征。
3 双峰法选择阈值
双峰法的原理认为图像由前景和背景或者两族颜色组成,在灰度直方图上,两族颜
色像素灰度值的分布形成山峰状态。在双峰之间的最低谷处就是图像分割的阈值所
在,根据这一原理可以简单算出阈值,进行图像分割。Show一下直方图即可确定阈
值。但是这种方法容易丢失一些图像细节
即下图中,以Zt为阈值进行二值化分割,可以将目标和背景分割开。
4 迭代法选取阈值
4.1 求出图象的最大灰度值和最小灰度值,分别记为Pmax和Pmin,令初始阈值T0=(Pmax+Pmin)/2;
4.2 根据阈值T(k)(k=0,1,2...,k)将图象分割为前景和背景,分别求出两者的平均灰度值H1和H2;
4.3 求出新阈值T(k+1)=(H1+H2)/2;
4.4 若T(k)=T(k+1),则所得即为阈值;否则转2,迭代计算
5 大津法选择阈值
Otsu实现思路
5.1 计算0~255各灰阶对应的像素个数,保存至一个数组中,该数组下标是灰度值,保存内容是当前灰度值对应像素数
5.2 计算背景图像的平均灰度、背景图像像素数所占比例
5.3 计算前景图像的平均灰度、前景图像像素数所占比例
5.4 遍历0~255各灰阶,计算并寻找类间方差极大值
大津法是属于最大类间方差法,它是自适应计算单阈值的简单高效方法,或者叫(Otsu)大津法由大津于1979年提出,对图像Image,记t为前景与背景的分割阈值,前景点数占图像比例为w0,平均灰度为u0;背景点数占图像比例为w1,平均灰度为u1。图像的总平均灰度为:u=w0u0+w1u1。从最小灰度值到最大灰度值遍历t,当t使得值g=w0(u0-u)2+w1(u1-u)2 最大时t即为分割的最佳阈值。对大津法可作如下理解:
该式实际上就是类间方差值,阈值t分割出的前景和背景两部分构成了整幅图像,而前景取值u0,概率为 w0,背景取值u1,概率为w1,总均值为u,根据方差的定义即得该式。因方差是灰度分布均匀性的一种度量,方差值越大,说明构成图像的两部分差别越大, 当部分目标错分为背景或部分背景错分为目标都会导致两部分差别变小,因此使类间方差最大的分割意味着错分概率最小。直接应用大津法计算量较大,因此一般采用了等价的公式g=w0w1(u0-u1)2。
6 由灰度拉伸选择阈值
大津法是较通用的方法,但是它对两群物体在灰度不明显的情况下会丢失一些整体信息。因此为了解决这种现象采用灰度拉伸的增强大津法。在大津法的思想上增加灰度的级数来增强前两群物体的灰度差。对于原来的灰度级乘上同一个系数,从而扩大了图像灰度的级数。试验结果表明不同的拉伸系数,分割效果差别比较大。
二、源代码
function varargout = Gui_Main(varargin)
% GUI_MAIN MATLAB code for Gui_Main.fig
% GUI_MAIN, by itself, creates a new GUI_MAIN or raises the existing
% singleton*.
%
% H = GUI_MAIN returns the handle to a new GUI_MAIN or the handle to
% the existing singleton*.
%
% GUI_MAIN('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in GUI_MAIN.M with the given input arguments.
%
% GUI_MAIN('Property','Value',...) creates a new GUI_MAIN or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before Gui_Main_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to Gui_Main_OpeningFcn via varargin.
%
% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
% instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help Gui_Main
% Last Modified by GUIDE v2.5 20-Jun-2020 15:07:10
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @Gui_Main_OpeningFcn, ...
'gui_OutputFcn', @Gui_Main_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before Gui_Main is made visible.
function Gui_Main_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to Gui_Main (see VARARGIN)
% Choose default command line output for Gui_Main
clc;
axes(handles.axes1); cla reset; box on; set(gca, 'XTickLabel', [], 'YTickLabel', []);
axes(handles.axes2); cla reset; box on; set(gca, 'XTickLabel', [], 'YTickLabel', []);
axes(handles.axes3); cla reset; box on; set(gca, 'XTickLabel', [], 'YTickLabel', []);
axes(handles.axes4); cla reset; box on; set(gca, 'XTickLabel', [], 'YTickLabel', []);
set(handles.text1, 'string', '');
handles.output = hObject;
handles.file = [];
handles.Plate = [];
handles.bw = [];
handles.words = [];
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes Gui_Main wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = Gui_Main_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
% --------------------------------------------------------------------
function uipushtool1_ClickedCallback(hObject, eventdata, handles)
% hObject handle to uipushtool1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
[filename, pathname] = uiputfile({'*.jpg;*.tif;*.png;*.gif','All Image Files';...
'*.*','All Files' }, '保存结果', ...
'Result\result.jpg');
if isempty(filename)
return;
end
file = fullfile(pathname, filename);
f = getframe(gcf);
f = frame2im(f);
imwrite(f, file);
msgbox('保存结果图像成功!', '提示信息', 'modal');
% --------------------------------------------------------------------
% --- Executes on button press in pushbutton6.
function pushbutton6_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton6 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% 载入车牌图像
set(handles.text_result, 'string', '');
axes(handles.axes1); cla reset; box on; set(gca, 'XTickLabel', [], 'YTickLabel', []);
axes(handles.axes2); cla reset; box on; set(gca, 'XTickLabel', [], 'YTickLabel', []);
axes(handles.axes3); cla reset; box on; set(gca, 'XTickLabel', [], 'YTickLabel', []);
axes(handles.axes4); cla reset; box on; set(gca, 'XTickLabel', [], 'YTickLabel', []);
set(handles.text1, 'string', '');
handles.file = [];
handles.Plate = [];
handles.bw = [];
handles.words = [];
[filename, pathname, filterindex] = uigetfile({'*.jpg;*.tif;*.png;*.gif','All Image Files';...
'*.*','All Files' }, '选择待处理图像', ...
'images\car.jpg');
if filename == 0
return;
end
file = fullfile(pathname, filename);
Img = imread(file);
[y, ~, ~] = size(Img);
if y > 800
rate = 800/y;
Img1 = imresize(Img, rate);
else
Img1 = Img;
end
axes(handles.axes1);
imshow(Img1); title('原图像', 'FontWeight', 'Bold');
handles.Img = Img;
handles.file = file;
guidata(hObject, handles);
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
if isempty(handles.file)
msgbox('请载入待检测图像', '提示信息', 'modal');
return;
end
[Plate, ~, Loc] = Pre_Process(handles.Img, [], 0);
axes(handles.axes1); hold on;
row = Loc.row;
col = Loc.col;
plot([col(1) col(2)], [row(1) row(1)], 'g-', 'LineWidth', 3);
plot([col(1) col(2)], [row(2) row(2)], 'g-', 'LineWidth', 3);
plot([col(1) col(1)], [row(1) row(2)], 'g-', 'LineWidth', 3);
plot([col(2) col(2)], [row(1) row(2)], 'g-', 'LineWidth', 3);
hold off;
axes(handles.axes2); cla reset; box on; set(gca, 'XTickLabel', [], 'YTickLabel', []);
imshow(Plate, []); title('车牌区域图像', 'FontWeight', 'Bold');
handles.Plate = Plate;
guidata(hObject, handles);
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
if isempty(handles.Plate)
msgbox('请先进行车牌区域标定操作!', '提示信息', 'modal');
return;
end
bw = Plate_Process(handles.Plate, 0);
axes(handles.axes3); cla reset; box on; set(gca, 'XTickLabel', [], 'YTickLabel', []);
imshow(bw, []); title('车牌区域二值图像', 'FontWeight', 'Bold');
handles.bw = bw;
guidata(hObject, handles);
% --- Executes on button press in pushbutton3.
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton3 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
if isempty(handles.bw)
msgbox('请先进行车牌区域二值化操作!', '提示信息', 'modal');
return;
end
三、运行结果
四、备注
版本:2014a
完整代码或代写加1564658423