✅博主简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,Matlab项目合作可私信。
🍎个人主页:海神之光
🏆代码获取方式:
海神之光Matlab王者学习之路—代码获取方式
⛳️座右铭:行百里者,半于九十。
更多Matlab仿真内容点击👇
Matlab图像处理(进阶版)
路径规划(Matlab)
神经网络预测与分类(Matlab)
优化求解(Matlab)
语音处理(Matlab)
信号处理(Matlab)
车间调度(Matlab)
⛄一、答题卡简介
本案例研究答题卡识别软件的设计与开发,集成了图像分割、模式识别等领域的功能模块,涉及计算机图像处理的一系列知识。通过图像处理技术,系统能够识别答题卡图像的答案选项,再通过输入正确答案的答题卡并与之对照,进而对学生答题卡进行判别并计算出分数。本案例侧重于图像识别方面的实现,应用了图像校正、模式识别等方面的算法。
1 理论基础
答题卡自动阅卷系统通过获取答题卡图像作为系统输入,并通过计算机处理、自动识别填涂标记,存入数据库完成阅卷。在图像数字化的过程中,受设备、环境等因素的影响,答题卡图像的质量在一定程度上下降,影响自动阅卷的准确率,甚至导致无法正常阅卷。因此,要对所获取的图像进行一系列的预处理,滤去干扰、噪声,做几何校正、彩色校正等操作,并进行二值化处理,以确保后续步骤能顺利进行。
1.1 图像二值化
彩色图像经过灰度化处理后得到灰度图,每个像素都仅有一个灰度值,该灰度值的大小决定了像素的亮暗程度。在答题卡自动识别实验中,根据答题卡图像答案目标的色彩特点,为了方便地进行目标答案的检测和识别,我们需要对灰度图像进行二值化处理,也就是说各像素的灰度值只有0和1两个取值,用来表示黑白两种颜色,这样可以大大减少计算的数据量。
在对答题卡图像进行二值化的过程中,阈值的选取是关键,直接影响到目标答案是否能被正确识别。根据二值化过程中的阈值选取的来源不同,阈值选取方法可以分为全局和局部两种。鉴于答题卡图像的应用场景,不同考生填涂答题卡的深浅度往往不同。如果采用由用户指定阈值的方法,则可能会产生对每张答题卡都需要进行阈值调整的要求,而且在光照不均匀等因素的影响下往往会出现目标区域二值化异常的现象。因此,在本案例中采用局部平均阈值法来自动确定阈值,当像素点的灰度值小于阈值时,则将该点的数值置为0,否则将数值置为1。该算法在不同的图像区域所选择的阈值会自动调整,也消除了光照不均匀等因素的干扰,同时在光照明暗变化时能自动调整阈值的大小。等待系统载入答题卡图像,进行灰度化化等预处理后再进行二值化,将有效突出答案目标的显示效果。
1.2 倾斜校正
在答题卡图像采集的过程中,由于种种原因,可能会导致所采集得到的答题卡图像有某种程度的倾斜,为了得到准确的阅卷结果,需要进行必要的倾斜纠正处理。答题卡图像的倾斜校正一般分为两步:第一步,查找倾斜角度;第二步,进行坐标变换,得到校正后的图像。其中, 常用的倾斜角度查找方法有两种:一种是利用Hough变换来找出倾斜角度;另一种是利用角点检测来找出倾斜角度。根据答题卡图像样式固定的特点,本案例采用Hough变换来进行倾斜角度的计算。
Hough变换作为一种参数空间变换算法, 自从1962年被Hough提出之后, 便成为直线和其他参数化形状检测的重要工具。Hough变换具有较强的稳定性和鲁棒性, 可以在一定程度上避免噪声的影响, 而且易于并行运算2。因此, Hough变换被不断地研究并取得大量进展, Duda和Halt将极坐标引入Hough变换, 使这种方法可以更加有效地用于直线检测和其他任意几何形状的检测。Ballard提出了非解析任意形状的R表法, 将Hough变换推广到对任意方向和范围的非解析任意形状的识别, 这种方法被称为广义Hough变换。
直线y=mx+b可用极坐标表示为:
也可表示为:
其中,1式中的(r,6)定义了一个从原点到该直线最近点的向量,显然,该向量与该直线垂直,如图所示。
假设以参数r和0构成一个二维空间,则x、y平面上的任意一条直线对应了r、0平面上的一个点。因此, x、y平面上的任意一条直线的Hough变换就是寻找r、0平面上的一个对应点的过程。
假设x、y平面上有一个特定的点(xo,yo),经过该点的直线可以有很多条,每一条都对应了r、0平面中的一个点,这些点必须是满足以xo、yo作为常量时的1式。因此,根据1式的定义可以发现,在参数空间与x、y空间中所有这些直线对应点的轨迹是一条正弦型曲线,即x、y平面上的任意一点对应了r、0平面上的一条正弦曲线。如果有一组位于由参数ro和0决定的直线上的边缘点,则每个边缘点对应了r、0空间的一条正弦型曲线。由于这些曲线均对应了同一条直线参数,因此所有这些曲线必交于点
(ro,0o)。
在实际计算的过程中,为了找出这些点所构成的直线段,我们可以将r、0空间进行网格化,进而将其量化成许多小格,并初始化各小格的计数累加器。根据每一个(x0,yo)点的极坐标公式,可以根据其代入0的量化值,算出各个r的值,如果经量化后的值落在某个小格内,则使该小格的计数累加器加1;当全部(x,y)点变换后,对小格计数器进行统计,包含较大计数值的小格对应于共线点,并且(r,0)可作为直线拟合参数;包含较小计数值的小格一般对应于非共线点,丢弃不用。通过以上过程可以看出,如果r、0网格量化度量过大,则其参数空间的聚合效果较差,进而很难查找直线的准确的r、0参数;同理,如果r、0网格量化度量过小,则计算量会随之增大,影响查找效率。因此,在计算过程中需要综
合考虑这两方面,选择合适的网格量化度量值2。
由于Hough变换需要进行网格扫描处理, 运行速度往往较慢, 因此在进行直线检测和倾斜角度计算时,需要考虑的一个重要因素就是计算量的问题。其中,计算量与搜索角度步长0, 和搜索角度范围0, 密切相关。因此, 采用多级Hough变换, 通过设置角度搜索步长由大到小来进行直线检测和倾斜角度计算, 可以有效降低算法的计算量。多级Hough变换首先用较大的0,和0,以求出倾斜角度的大致范围,这类似于人眼主观估计的过程。然后用较小的0,和0,对倾斜角度进行细化处理,对于某些应用场景甚至可以求出约0.02°的倾斜, 这类似于人眼仔细估计的过程。因此, 采用多级Hough变换比直接应用Hough变换在运算速度上有了较大提高。
在计算答题卡图像的倾斜角度时,为了消除涂抹区域部均匀的影响,对已获取的满足上述特征的极大值对应的倾斜角度,可采用算术平均的方式进行优化处理。假设每行答题区对应的倾斜角度为0;(i=1,2,…,N,N通常为答题区的总行数),则图像的倾斜角度0m
由3式给出:
获取答题卡图像的倾斜角度后,可以对图像进行旋转处理。假设点(x.,)o)绕点(a,b)旋转0度后坐标为(x,y),旋转后中心坐标为(c,d),则:
图像旋转可能会引起图像的高度和宽度范围的改变,结合答题卡图像周边区域的特点,我们对旋转图像超出范围的周边区域进行了删除处理。同时,为了尽可能保持图像的完整性,在进行旋转时以图像的中心位置作为旋转中心进行计算,对答题卡图像进行倾斜校正的效果。
1.3 图像分割
图像分割是图像处理中常用的关键步骤之一,本案例涉及对答题卡图像有效区域的检测和分割。一般情况下,对灰度图像的分割通常可基于像素灰度值的两个性质:不连续性和相似性。图像固定区域内部的像素一般都具有灰度相似性,而在不同区域之间的边界上一般具有灰度不连续性,也就是我们常说的区域边缘属性。因此,灰度图像分割方法一般可以分为基于区域的方法和基于边界的方法。前者利用区域内的灰度相似性进行分割,后者利用区域间的灰度不连续性进行分割。根据分割过程中选择的运算策略不同,分割算法又可分为并行算法和串行算法。在并行算法过程中,所有检测和分割都可独立和同时地进行,利于提高运算效率曰。在串行算法过程中,后续的处理流程要用到之前的步骤得到的结果,要求程序运行具有连续性。
基于区域的分割方法
基于区域的分割方法以区域内像素的相似性特征为依据,将图像划分成一系列有意义的独立区域,实现分割的目标。图像进行区域分割一般有以下特征。
(1)一致性。图像分割后的区域应在某些特征方面表现出一致性,如灰度、颜色或纹理。
(2)单一性。区域内部目标分布单一,不能包含太多孔洞。
(3)差异性。区域内部的同一特征在相邻区域间应有明显的差异性。
(4)准确性。区域间的分割边界应该有光滑性,且边界的空间位置准确。
基于区域的分割方法常用的有灰度阈值法和区域增长法等,其特点是充分利用了区域内像素特征的相似性。
2 程序实现
本案例提出了一种能够有效识别答题卡的方法, 利用基于Hough变换的直线检测技术检测图像的倾斜度,对存在倾斜的图像进行旋转校正,最终实现答题卡答案的定位和检测。其中,在识别过程中使用像素灰度积分统计的方法,具有较低的误识别率,能够准确定位答题卡的涂卡痕迹。下面介绍程序实现过程中的关键步骤。
2.1 图像灰度化
根据答题卡图像的自身特点,本实验要求输入的图片为灰度格式,并将采集到的答题卡图片经灰度化处理后存储到硬盘的指定文件夹,用于检测识别。采用灰度图像进行存储能显著减少文件所占用的硬盘空间,而且能提高图像处理识别的速度。一般而言,可采用加权平均值法对原始RGB图像进行灰度化处理, 该方法的主要思想是从原图像中取R、G、B各层像素值并经过加权求和得到灰度图的亮度值。现实生活中,人眼对绿色(G)敏感度最高,对红色®敏感度次之,对蓝色(B)敏感度最低,因此为了选择合适的权值对象使之能够输出合理的灰度图像,权值系数应该满足G>R>B.实验和理论证明,当R、G、B的权值系数分别为0.299、0.587和0.114时,能够得到最适合人眼观察的灰度图像。
2.2 灰度图像二值化
图像二值化是图像处理的基本技术之一,而阈值的选取则是图像二值化的关键步骤。一般而言,对于灰度图像来说,可适当选择一个或若干个灰度值T(0≤T≤255)来进行二值化,将目标和背景分开,这个灰度值T就称为阈值。因此,对于答题卡图像来说,根据考生填涂答题卡的答案目标区域特点,可选择适当的阈值T进行二值化。当像素点的灰度值小于T时,则将该点的颜色值置为“0”,否则将其颜色值置为“1”。这样就得到了只包含黑白两种颜色的二值图像。
2.3 图像平滑滤波
图像平滑滤波是一种实用的数字图像处理技术,主要是为了减少图像的噪声,常用的有中值滤波、均值滤波等方法。中值滤波指将像素邻域的灰度值进行排序后取中位数值作为中心像素的新灰度值。答题卡图像在采集过程中经常会遇到随机噪声的干扰,该噪声一般是邻域中亮度值发生随机突变的像素,并且经排序后往往出现在序列的队首或队尾,故经中值滤波后答题卡图像的随机噪声能得到有效消除。
2.4 图像校正
对答题卡图像进行校正处理主要是进行图像旋转操作,便于后续的检测和识别。图像旋转的算法很多,本实验采用的算法思路为:将需调整的答题卡图像读取到内存中,计算图像的倾斜角度,依据所得的倾斜角度旋转图像,得到校正图像。根据答题卡图像的特点,答题卡的有效信息往往位于整幅图像的特定部位,一般包括考生准考证号区域、答案区域和考试科目区域三大部分,因此对这些区域进行精确的定位即可提取图像的特征信息。答题卡图像一般由明确的矩形框和直线组成,在进行区域定位时选择Hough变换来进行直线检测, 进而获取定位信息, 计算倾斜角度, 之后进行图像旋转来得到校正结果。
2.5 填写检查
考生在涂卡时,由于种种原因可能会出现重选、漏选等错误,可根据对识别结果的影响分两种情况进行处理:一种情况是如果考生的基本信息如专业、科目、班级、学号、试卷类型等客观信息出现重选、漏选错误,则在系统识别后会立即给出错误提示,要求确认修改图像或重新采集图像;另一种情况是如果考生填涂答案时出现重选、漏选错误,则可按答案选择错误对待,并将识别结果记入存储结构。最后,系统根据事先录入的标准答案与识别存储结构进行自动评分,从而获得每名考生的考试成绩信息。
⛄二、部分源代码
function varargout = MYGUI(varargin)
% MYGUI MATLAB code for MYGUI.fig
% MYGUI, by itself, creates a new MYGUI or raises the existing
% singleton*.
%
% H = MYGUI returns the handle to a new MYGUI or the handle to
% the existing singleton*.
%
% MYGUI(‘CALLBACK’,hObject,eventData,handles,…) calls the local
% function named CALLBACK in MYGUI.M with the given input arguments.
%
% MYGUI(‘Property’,‘Value’,…) creates a new MYGUI or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before MYGUI_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to MYGUI_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 MYGUI
% Last Modified by GUIDE v2.5 27-Feb-2024 18:48:36
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct(‘gui_Name’, mfilename, …
‘gui_Singleton’, gui_Singleton, …
‘gui_OpeningFcn’, @MYGUI_OpeningFcn, …
‘gui_OutputFcn’, @MYGUI_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 MYGUI is made visible.
function MYGUI_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 MYGUI (see VARARGIN)
% Choose default command line output for MYGUI
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes MYGUI wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% — Outputs from this function are returned to the command line.
function varargout = MYGUI_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 edit1_Callback(hObject, eventdata, handles)
% hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,‘String’) returns contents of edit1 as text
% str2double(get(hObject,‘String’)) returns contents of edit1 as a double
% — Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
% hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,‘BackgroundColor’), get(0,‘defaultUicontrolBackgroundColor’))
set(hObject,‘BackgroundColor’,‘white’);
end
% — 打开答案答题卡
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)
[filename,pathname]=uigetfile({‘.’;‘.bmp’;'.jpg’;‘.tif’;'.jpg’},‘选择图像’);
image=[pathname,filename];%合成路径+文件名
% 1 原图
f=imread(image);%读取图像
axes(handles.axes1);imshow(f);title(‘答案答题卡’);
% 2 对比度拉伸
I1 = Image_Normalize(f, 0); % 固定了大小
axes(handles.axes2);imshow(I1);title(‘亮度调节’);
% 3 高斯平滑滤波器,平滑处理,模板尺寸[3 3],sigma角0.5,平滑方式:高斯滤波
hsize = [3 3];
sigma = 0.5;
I2 = Image_Smooth(I1, hsize, sigma, 0);
axes(handles.axes3);imshow(I2);title(‘高斯平滑处理’);
% 4 灰度化,二值化
if ndims(I2) == 3
I2 = rgb2gray(I2); % 灰度化
end
I2 = im2bw(I2, graythresh(f)); % 二值化
axes(handles.axes4);imshow(~I2);title(‘灰度化再二值化’);
% 5 开闭操作
I2 = imopen(I2, strel(‘square’, 3));
I2 = imclose(I2, strel(‘square’, 4));
axes(handles.axes5);imshow(~I2);title(‘开闭操作后’);
% 6 腐蚀操作-使方块变大
bw = imerode(I2, strel(‘square’, 4));
axes(handles.axes6);imshow(imcomplement(bw)), title(‘腐蚀操作后’);
% 7 哈夫变换-图像校正
bw=imcomplement(bw);
[h,t,r]=hough(bw,‘RhoResolution’,2,‘ThetaResolution’,2);
P=houghpeaks(h,2);
lines=houghlines(bw,t,r,P,‘FillGap’,15,‘Minlength’,60);
axes(handles.axes7);imshow(bw);title(‘拟合直线’);
hold on;
max_len=0;
len=0;
for i=1:length(lines)
xy=[lines(i).point1;lines(i).point2];
len = norm(lines(i).point1-lines(i).point2); %直线的长度
plot(xy(:,1),xy(:,2),‘LineWidth’,2,‘Color’,‘g’);
plot(xy(:,1),xy(1,2),‘x’,‘LineWidth’,2,‘Color’,‘y’);
plot(xy(:,1),xy(2,2),‘x’,‘LineWidth’,2,‘Color’,‘r’);
if len > max_len
max_len = len;
xy_long = xy;
index=i;
end
end
[theta] = findMidCenter(bw,lines(index).point1,lines(index).point2);
if abs(theta)>1
B=imrotate(bw,theta);% 逆时针
else
B=bw;
end
%%
% 6 画基准线, 分割信息部分和答案部分
% 再进行画线,画出2条基准线
[h t r] = hough(B);
peaks = houghpeaks(h, 3);
lines = houghlines(B, t, r, peaks, ‘FillGap’, 50, ‘MinLength’, 7);
% figure, imshow(B), title(‘分割前’), hold on;
for i = 1 : length(lines)
xy = [lines(i).point1; lines(i).point2];
if abs(lines(i).point1(2) - lines(i).point2(2)) <= 50 % 竖线条必然大于十
len(i) = norm(lines(i).point1 - lines(i).point2); % 两天横线条线的高度
else
len(i) = -1;
a=max(lines(i).point1(1,1),lines(i).point2(1,1))-3;
B(:,a:size(B,2)) = 0;
end
plot(xy(:, 1), xy(:, 2), ‘LineWidth’, 4, ‘Color’, ‘red’);
plot(lines(i).point1(1), lines(i).point1(2), ‘bo’);
plot(lines(i).point2(1), lines(i).point2(2), ‘yo’);
xyD{i} = xy;
end
axes(handles.axes7);imshow(B);title(‘哈夫变换-图像校正后’);
[len, ind] = sort(len(😃, ‘descend’); % 降序排序
for i = 1 : length(ind)
xyN{i} = xyD{ind(i)};
end
up = B;
down = B;
u = xyN{1};
d = xyN{2};
if u(1, 2) > d(1, 2) % 确保u在上面
t = u;
u = d;
d = t;
end
up((u(1, 2)-15): 1 : (d(1, 2)+8), 😃 = 0;
down(1 : (u(1, 2)+8), 😃 = 0;
down((d(1, 2)-11):size(B,1), 😃 = 0;
% figure, imshow(up), title(‘信息部分’);
% figure, imshow(down), title(‘答题部分’);
%%
% 8 定位答案
% 画横线
[L1, num1] = bwlabel(B);
%上区域属性信息
stats1 = regionprops(L1);
axes(handles.axes8);imshow(B, []); title(‘标记图像’);
hold on;
for i = 1 : num1
temp = stats1(i).Centroid;
plot(temp(1), temp(2), ‘rp’);
end
rects = cat(1,stats1.BoundingBox);
% figure;imshow(B);
for i = 1:size(rects, 1)
rectangle(‘position’, rects(i, 😃, ‘EdgeColor’, ‘r’);
end
% 按横坐标递减排序
x = cat(1,stats1.Centroid); % 默认按横坐标升序排序
x1=x(end-33+1:end,:);
% 再按高度递增排序
[x1, ind1] = sortrows(x1,2);
% 画横线
axes(handles.axes9);imshow(B);
for i=[1:10,16:19,22:25]
hold on
% 纵坐标已知!!!!
plot([1,size(B,2)],[x1(i,2),x1(i,2)], ‘LineWidth’, 1, ‘Color’, ‘red’);
end
% 画竖线1
if(length(x)==70)
% 没有多余的块块
x2=x(1:37,:); % 左边的块块!~
else
x2=x(1:38,:);
end
% 在学号区间的部分,index是x2的index
index1=find(x2(:,2)>(x1(1,2)-5) & x2(:,2)<(x1(10,2)+5));
for i=[index1’]
hold on
plot([x2(i,1),x2(i,1)],[(x1(1,2)-5),(x1(10,2)+5)], ‘LineWidth’, 1, ‘Color’, ‘blue’);
end
% 画竖线2
% 在学号区间的部分,index是x2的index
index2=find(x2(:,2)>(x1(16,2)-15) & x2(:,2)<(x1(19,2)+15));
for i=[index2’]
hold on
plot([x2(i,1),x2(i,1)],[(x1(16,2)-15),(x1(19,2)+15)], ‘LineWidth’, 1, ‘Color’, ‘blue’);
end
% 画竖线3
% 在学号区间的部分,index是x2的index
index3=find(x2(:,2)>(x1(22,2)-15) & x2(:,2)<(x1(25,2)+15));
for i=[index3’]
hold on
plot([x2(i,1),x2(i,1)],[(x1(22,2)-15),(x1(25,2)+15)], ‘LineWidth’, 1, ‘Color’, ‘blue’);
end
title(‘定位答案’);
% 10 原图定位
if abs(theta)>1
R=imrotate(I1,theta);% 逆时针
else
R=I1;
end
axes(handles.axes10);imshow®;title(‘原图定位’);
for i=[1:10,16:19,22:25]
hold on
% 纵坐标已知!!!!
plot([1,size(B,2)],[x1(i,2),x1(i,2)], ‘LineWidth’, 1, ‘Color’, ‘red’);
end
for i=[index1’]
hold on
plot([x2(i,1),x2(i,1)],[(x1(1,2)-5),(x1(10,2)+5)], ‘LineWidth’, 1, ‘Color’, ‘blue’);
end
for i=[index2’]
hold on
plot([x2(i,1),x2(i,1)],[(x1(16,2)-15),(x1(19,2)+15)], ‘LineWidth’, 1, ‘Color’, ‘blue’);
end
for i=[index3’]
hold on
plot([x2(i,1),x2(i,1)],[(x1(22,2)-15),(x1(25,2)+15)], ‘LineWidth’, 1, ‘Color’, ‘blue’);
end
% 11 答案-标记答案
% x2是中心坐标,二维数组
% 信息 10*11
xinfo=x2(index1,1);
yinfo=x1(1:10,2);
% 答题1 4*15
xanswer1=x2(index2,1);
yanswer1=x1(16:19,2);
% 答题2 4*5
xanswer2=x2(index3,1);
yanswer2=x1(22:25,2);
% 可以使用中心到上下点最小来判断(不在点上的辅助判断方法)
% 直接用高度差判断就够了
% 信息矩阵
for i=1:length(xinfo)
% 图卡块的纵坐标
h=x2(index1(i),2);
for j=1:length(yinfo)
dh1(j,i)=abs(h-yinfo(j));
end
end
[a,b1]=min(dh1);
b1=b1-1;
% 答案1
for i=1:length(xanswer1)
% 图卡块的纵坐标
h=x2(index2(i),2);
for j=1:length(yanswer1)
dh2(j,i)=abs(h-yanswer1(j));
end
end
[a,b2]=min(dh2);
b2;
% 答案2
for i=1:length(xanswer2)
% 图卡块的纵坐标
h=x2(index3(i),2);
for j=1:length(yanswer2)
dh3(j,i)=abs(h-yanswer2(j));
end
end
[a,b3]=min(dh3);
b3;
b=[b2,b3];
save answer.mat b
s=‘’;
for i=1:20
switch b(i)
case 1
s0=‘A’;
case 2
s0=‘B’;
case 3
s0=‘C’;
case 4
s0=‘D’;
end
s=[s,’ ',s0];
end
set(handles.edit1,‘string’,s);
% — 打开批改答题卡
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)
[filename,pathname]=uigetfile({‘.’;‘.bmp’;'.jpg’;‘.tif’;'.jpg’},‘选择图像’);
image=[pathname,filename];%合成路径+文件名
% 1 原图
f=imread(image);%读取图像
axes(handles.axes1);imshow(f);title(‘批改答题卡’);
handles.f = f;
guidata(hObject, handles);
% — 一键识别
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)
f=handles.f;
% 2 对比度拉伸
I1 = Image_Normalize(f, 0); % 固定了大小
axes(handles.axes2);imshow(I1);title(‘亮度调节’);
% 3 高斯平滑滤波器,平滑处理,模板尺寸[3 3],sigma角0.5,平滑方式:高斯滤波
hsize = [3 3];
sigma = 0.5;
I2 = Image_Smooth(I1, hsize, sigma, 0);
axes(handles.axes3);imshow(I2);title(‘高斯平滑处理’);
% 4 灰度化,二值化
if ndims(I2) == 3
I2 = rgb2gray(I2); % 灰度化
end
I2 = im2bw(I2, graythresh(f)); % 二值化
axes(handles.axes4);imshow(~I2);title(‘灰度化再二值化’);
% 5 开闭操作
I2 = imopen(I2, strel(‘square’, 3));
I2 = imclose(I2, strel(‘square’, 4));
axes(handles.axes5);imshow(~I2);title(‘开闭操作后’);
% 6 腐蚀操作-使方块变大
bw = imerode(I2, strel(‘square’, 4));
axes(handles.axes6);imshow(imcomplement(bw)), title(‘腐蚀操作后’);
% 7 哈夫变换-图像校正
bw=imcomplement(bw);
[h,t,r]=hough(bw,‘RhoResolution’,2,‘ThetaResolution’,2);
P=houghpeaks(h,2);
lines=houghlines(bw,t,r,P,‘FillGap’,15,‘Minlength’,60);
axes(handles.axes7);imshow(bw);title(‘拟合直线’);
hold on;
max_len=0;
len=0;
for i=1:length(lines)
xy=[lines(i).point1;lines(i).point2];
len = norm(lines(i).point1-lines(i).point2); %直线的长度
plot(xy(:,1),xy(:,2),‘LineWidth’,2,‘Color’,‘g’);
plot(xy(:,1),xy(1,2),‘x’,‘LineWidth’,2,‘Color’,‘y’);
plot(xy(:,1),xy(2,2),‘x’,‘LineWidth’,2,‘Color’,‘r’);
if len > max_len
max_len = len;
xy_long = xy;
index=i;
end
end
[theta] = findMidCenter(bw,lines(index).point1,lines(index).point2);
if abs(theta)>1
B=imrotate(bw,theta);% 逆时针
else
B=bw;
end
%%
% 6 画基准线, 分割信息部分和答案部分
% 再进行画线,画出2条基准线
[h t r] = hough(B);
peaks = houghpeaks(h, 3);
lines = houghlines(B, t, r, peaks, ‘FillGap’, 50, ‘MinLength’, 7);
% figure, imshow(B), title(‘分割前’), hold on;
for i = 1 : length(lines)
xy = [lines(i).point1; lines(i).point2];
if abs(lines(i).point1(2) - lines(i).point2(2)) <= 50 % 竖线条必然大于十
len(i) = norm(lines(i).point1 - lines(i).point2); % 两天横线条线的高度
else
len(i) = -1;
a=max(lines(i).point1(1,1),lines(i).point2(1,1))-3;
B(:,a:size(B,2)) = 0;
end
plot(xy(:, 1), xy(:, 2), ‘LineWidth’, 4, ‘Color’, ‘red’);
plot(lines(i).point1(1), lines(i).point1(2), ‘bo’);
plot(lines(i).point2(1), lines(i).point2(2), ‘yo’);
xyD{i} = xy;
end
axes(handles.axes7);imshow(B);title(‘哈夫变换-图像校正后’);
[len, ind] = sort(len(😃, ‘descend’); % 降序排序
for i = 1 : length(ind)
xyN{i} = xyD{ind(i)};
end
up = B;
down = B;
u = xyN{1};
d = xyN{2};
if u(1, 2) > d(1, 2) % 确保u在上面
t = u;
u = d;
d = t;
end
⛄三、运行结果
⛄四、matlab版本及参考文献
1 matlab版本
2014a
2 参考文献
[1]林恒青,戴立庆.基于局部自适应阈值分割和Hough变换的答题卡识别算法[J].桂林航天工业学院学报. 2021,26(03)
3 备注
简介此部分摘自互联网,仅供参考,若侵权,联系删除
🍅 仿真咨询
1 各类智能优化算法改进及应用
1.1 PID优化
1.2 VMD优化
1.3 配电网重构
1.4 三维装箱
1.5 微电网优化
1.6 优化布局
1.7 优化参数
1.8 优化成本
1.9 优化充电
1.10 优化调度
1.11 优化电价
1.12 优化发车
1.13 优化分配
1.14 优化覆盖
1.15 优化控制
1.16 优化库存
1.17 优化路由
1.18 优化设计
1.19 优化位置
1.20 优化吸波
1.21 优化选址
1.22 优化运行
1.23 优化指派
1.24 优化组合
1.25 车间调度
1.26 生产调度
1.27 经济调度
1.28 装配线调度
1.29 水库调度
1.30 货位优化
1.31 公交排班优化
1.32 集装箱船配载优化
1.33 水泵组合优化
1.34 医疗资源分配优化
1.35 可视域基站和无人机选址优化
2 机器学习和深度学习分类与预测
2.1 机器学习和深度学习分类
2.1.1 BiLSTM双向长短时记忆神经网络分类
2.1.2 BP神经网络分类
2.1.3 CNN卷积神经网络分类
2.1.4 DBN深度置信网络分类
2.1.5 DELM深度学习极限学习机分类
2.1.6 ELMAN递归神经网络分类
2.1.7 ELM极限学习机分类
2.1.8 GRNN广义回归神经网络分类
2.1.9 GRU门控循环单元分类
2.1.10 KELM混合核极限学习机分类
2.1.11 KNN分类
2.1.12 LSSVM最小二乘法支持向量机分类
2.1.13 LSTM长短时记忆网络分类
2.1.14 MLP全连接神经网络分类
2.1.15 PNN概率神经网络分类
2.1.16 RELM鲁棒极限学习机分类
2.1.17 RF随机森林分类
2.1.18 SCN随机配置网络模型分类
2.1.19 SVM支持向量机分类
2.1.20 XGBOOST分类
2.2 机器学习和深度学习预测
2.2.1 ANFIS自适应模糊神经网络预测
2.2.2 ANN人工神经网络预测
2.2.3 ARMA自回归滑动平均模型预测
2.2.4 BF粒子滤波预测
2.2.5 BiLSTM双向长短时记忆神经网络预测
2.2.6 BLS宽度学习神经网络预测
2.2.7 BP神经网络预测
2.2.8 CNN卷积神经网络预测
2.2.9 DBN深度置信网络预测
2.2.10 DELM深度学习极限学习机预测
2.2.11 DKELM回归预测
2.2.12 ELMAN递归神经网络预测
2.2.13 ELM极限学习机预测
2.2.14 ESN回声状态网络预测
2.2.15 FNN前馈神经网络预测
2.2.16 GMDN预测
2.2.17 GMM高斯混合模型预测
2.2.18 GRNN广义回归神经网络预测
2.2.19 GRU门控循环单元预测
2.2.20 KELM混合核极限学习机预测
2.2.21 LMS最小均方算法预测
2.2.22 LSSVM最小二乘法支持向量机预测
2.2.23 LSTM长短时记忆网络预测
2.2.24 RBF径向基函数神经网络预测
2.2.25 RELM鲁棒极限学习机预测
2.2.26 RF随机森林预测
2.2.27 RNN循环神经网络预测
2.2.28 RVM相关向量机预测
2.2.29 SVM支持向量机预测
2.2.30 TCN时间卷积神经网络预测
2.2.31 XGBoost回归预测
2.2.32 模糊预测
2.2.33 奇异谱分析方法SSA时间序列预测
2.3 机器学习和深度学习实际应用预测
CPI指数预测、PM2.5浓度预测、SOC预测、财务预警预测、产量预测、车位预测、虫情预测、带钢厚度预测、电池健康状态预测、电力负荷预测、房价预测、腐蚀率预测、故障诊断预测、光伏功率预测、轨迹预测、航空发动机寿命预测、汇率预测、混凝土强度预测、加热炉炉温预测、价格预测、交通流预测、居民消费指数预测、空气质量预测、粮食温度预测、气温预测、清水值预测、失业率预测、用电量预测、运输量预测、制造业采购经理指数预测
3 图像处理方面
3.1 图像边缘检测
3.2 图像处理
3.3 图像分割
3.4 图像分类
3.5 图像跟踪
3.6 图像加密解密
3.7 图像检索
3.8 图像配准
3.9 图像拼接
3.10 图像评价
3.11 图像去噪
3.12 图像融合
3.13 图像识别
3.13.1 表盘识别
3.13.2 车道线识别
3.13.3 车辆计数
3.13.4 车辆识别
3.13.5 车牌识别
3.13.6 车位识别
3.13.7 尺寸检测
3.13.8 答题卡识别
3.13.9 电器识别
3.13.10 跌倒检测
3.13.11 动物识别
3.13.12 二维码识别
3.13.13 发票识别
3.13.14 服装识别
3.13.15 汉字识别
3.13.16 红绿灯识别
3.13.17 虹膜识别
3.13.18 火灾检测
3.13.19 疾病分类
3.13.20 交通标志识别
3.13.21 卡号识别
3.13.22 口罩识别
3.13.23 裂缝识别
3.13.24 目标跟踪
3.13.25 疲劳检测
3.13.26 旗帜识别
3.13.27 青草识别
3.13.28 人脸识别
3.13.29 人民币识别
3.13.30 身份证识别
3.13.31 手势识别
3.13.32 数字字母识别
3.13.33 手掌识别
3.13.34 树叶识别
3.13.35 水果识别
3.13.36 条形码识别
3.13.37 温度检测
3.13.38 瑕疵检测
3.13.39 芯片检测
3.13.40 行为识别
3.13.41 验证码识别
3.13.42 药材识别
3.13.43 硬币识别
3.13.44 邮政编码识别
3.13.45 纸牌识别
3.13.46 指纹识别
3.14 图像修复
3.15 图像压缩
3.16 图像隐写
3.17 图像增强
3.18 图像重建
4 路径规划方面
4.1 旅行商问题(TSP)
4.1.1 单旅行商问题(TSP)
4.1.2 多旅行商问题(MTSP)
4.2 车辆路径问题(VRP)
4.2.1 车辆路径问题(VRP)
4.2.2 带容量的车辆路径问题(CVRP)
4.2.3 带容量+时间窗+距离车辆路径问题(DCTWVRP)
4.2.4 带容量+距离车辆路径问题(DCVRP)
4.2.5 带距离的车辆路径问题(DVRP)
4.2.6 带充电站+时间窗车辆路径问题(ETWVRP)
4.2.3 带多种容量的车辆路径问题(MCVRP)
4.2.4 带距离的多车辆路径问题(MDVRP)
4.2.5 同时取送货的车辆路径问题(SDVRP)
4.2.6 带时间窗+容量的车辆路径问题(TWCVRP)
4.2.6 带时间窗的车辆路径问题(TWVRP)
4.3 多式联运运输问题
4.4 机器人路径规划
4.4.1 避障路径规划
4.4.2 迷宫路径规划
4.4.3 栅格地图路径规划
4.5 配送路径规划
4.5.1 冷链配送路径规划
4.5.2 外卖配送路径规划
4.5.3 口罩配送路径规划
4.5.4 药品配送路径规划
4.5.5 含充电站配送路径规划
4.5.6 连锁超市配送路径规划
4.5.7 车辆协同无人机配送路径规划
4.6 无人机路径规划
4.6.1 飞行器仿真
4.6.2 无人机飞行作业
4.6.3 无人机轨迹跟踪
4.6.4 无人机集群仿真
4.6.5 无人机三维路径规划
4.6.6 无人机编队
4.6.7 无人机协同任务
4.6.8 无人机任务分配
5 语音处理
5.1 语音情感识别
5.2 声源定位
5.3 特征提取
5.4 语音编码
5.5 语音处理
5.6 语音分离
5.7 语音分析
5.8 语音合成
5.9 语音加密
5.10 语音去噪
5.11 语音识别
5.12 语音压缩
5.13 语音隐藏
6 元胞自动机方面
6.1 元胞自动机病毒仿真
6.2 元胞自动机城市规划
6.3 元胞自动机交通流
6.4 元胞自动机气体
6.5 元胞自动机人员疏散
6.6 元胞自动机森林火灾
6.7 元胞自动机生命游戏
7 信号处理方面
7.1 故障信号诊断分析
7.1.1 齿轮损伤识别
7.1.2 异步电机转子断条故障诊断
7.1.3 滚动体内外圈故障诊断分析
7.1.4 电机故障诊断分析
7.1.5 轴承故障诊断分析
7.1.6 齿轮箱故障诊断分析
7.1.7 三相逆变器故障诊断分析
7.1.8 柴油机故障诊断
7.2 雷达通信
7.2.1 FMCW仿真
7.2.2 GPS抗干扰
7.2.3 雷达LFM
7.2.4 雷达MIMO
7.2.5 雷达测角
7.2.6 雷达成像
7.2.7 雷达定位
7.2.8 雷达回波
7.2.9 雷达检测
7.2.10 雷达数字信号处理
7.2.11 雷达通信
7.2.12 雷达相控阵
7.2.13 雷达信号分析
7.2.14 雷达预警
7.2.15 雷达脉冲压缩
7.2.16 天线方向图
7.2.17 雷达杂波仿真
7.3 生物电信号
7.3.1 肌电信号EMG
7.3.2 脑电信号EEG
7.3.3 心电信号ECG
7.3.4 心脏仿真
7.4 通信系统
7.4.1 DOA估计
7.4.2 LEACH协议
7.4.3 编码译码
7.4.4 变分模态分解
7.4.5 超宽带仿真
7.4.6 多径衰落仿真
7.4.7 蜂窝网络
7.4.8 管道泄漏
7.4.9 经验模态分解
7.4.10 滤波器设计
7.4.11 模拟信号传输
7.4.12 模拟信号调制
7.4.13 数字基带信号
7.4.14 数字信道
7.4.15 数字信号处理
7.4.16 数字信号传输
7.4.17 数字信号去噪
7.4.18 水声通信
7.4.19 通信仿真
7.4.20 无线传输
7.4.21 误码率仿真
7.4.22 现代通信
7.4.23 信道估计
7.4.24 信号检测
7.4.25 信号融合
7.4.26 信号识别
7.4.27 压缩感知
7.4.28 噪声仿真
7.4.29 噪声干扰
7.5 无人机通信
7.6 无线传感器定位及布局方面
7.6.1 WSN定位
7.6.2 高度预估
7.6.3 滤波跟踪
7.6.4 目标定位
7.6.4.1 Dv-Hop定位
7.6.4.2 RSSI定位
7.6.4.3 智能算法优化定位
7.6.5 组合导航
8 电力系统方面
微电网优化、无功优化、配电网重构、储能配置