首页 > 行业资讯 > 【答题卡识别】基于hough变换答题卡判定与成绩统计含Matlab源码

【答题卡识别】基于hough变换答题卡判定与成绩统计含Matlab源码

时间:2022-05-01 来源: 浏览:

【答题卡识别】基于hough变换答题卡判定与成绩统计含Matlab源码

天天Matlab 天天Matlab
天天Matlab

TT_Matlab

博主简介:擅长智能优化算法、神经网络预测、信号处理、元胞自动机、图像处理、路径规划、无人机等多种领域的Matlab仿真,完整matlab代码或者程序定制加qq1575304183。

收录于合集 #图像处理matlab源码 557个

1 简介

本文实现一个基于 MATLAB的答题卡识别。MATLAB是一款商业数学软件,可用于科学计算和工程绘图,具有相应的功能函数,可以对图像进行标注和打印,还可以对指定的图像处理光照、色度等。而基于M ATLAB 的答题卡处理,首先,对答题卡进行归一化、平滑处理、灰度化、二值化的预处理,再运用 M ATALB 中的 Hough变换函数对答题卡进行直线检测,对答题卡直线定位,以便后续对答题卡进行矫正、滤波、分割区域、画网格线、标记,最后再通过一个图形用户界面显示答题卡上的填涂选项和答题卡分数。

2 部分代码

function [score,I4,I5] = SimplePaper_Inspection( filename) %输入参数: %filenames——包含需要判定的答题卡文件名 %读取图像 I = imread(filename); %预处理 I1 = Image_Normalize(I, 1 ); %平滑处理,模板尺寸[ 3 3 ],sigma角 0 . 5 ,平滑方式:高斯滤波 hsize = [ 3 3 ]; sigma = 0 . 5 ; I2 = Image_Smooth(I1, hsize, sigma, 1 ); %灰度化 I3 = Gray_Convert(I2, 1 ); %二值化 bw2 = Image_Binary(I3, 1 ); %hough变换 [~, ~, xy_long] = Hough_Process(bw2, I1, 1 ); %变换斜率 angle = Compute_Angle(xy_long); %图像旋转 [I4, bw3] = Image_Rotate(I1, bw2, angle* 1.8 , 1 ); %形态学滤波 [bw4, Loc1] = Morph_Process(bw3, 1 ); %hough检测区域分界线 [Len, XYn, xy_long] = Hough_Process(bw4, I4, 1 ); %区域分割 [bw5, bw6] = Region_Segmation(XYn, bw4, I4, 1 ); %区域标记 [stats1, stats2, Line] = Location_Label(bw5, bw6, I4, XYn, Loc1, 1 ); %区域分析 [Dom, Aom, Answer, Bn] = Analysis(stats1, stats2, Line, I4); savefigure12img( ’t.jpg’ ); I5=imread( ’t.jpg’ ); %成绩判定 score=jieguo(bw5); fprintf( ’选择题得分为%d’ ,score);%在command窗口输出成 %将答题卡图片转存到results文件夹 Write_Results(); function I1 = Image_Normalize(I, flag) if nargin < 2 flag = 1 ; end if size(I, 1 ) > 2000 I = imresize(I, 0 . 2 , ’bilinear’ ); end I1 = imadjust(I, [ 0 0 . 6 ], [ 0 1 ]); if flag figure( 1 ); subplot( 2 , 1 , 1 ); imshow(I, []); title( ’原图像’ , ’FontWeight’ , ’Bold’ ); subplot( 2 , 1 , 2 ); imshow(I1, []); title( ’归一化图像’ , ’FontWeight’ , ’Bold’ ); end end function I2 = Image_Smooth(I1, hsize, sigma, flag) if nargin < 4 flag = 1 ; end if nargin < 2 hsize = [ 3 3 ]; sigma = 0 . 5 ; end h = fspecial( ’gaussian’ , hsize, sigma); I2 = imfilter(I1, h, ’replicate’ ); if flag figure( 2 ); subplot( 2 , 1 , 1 ); imshow(I1, []); title( ’平滑前图像’ , ’FontWeight’ , ’Bold’ ); subplot( 2 , 1 , 2 ); imshow(I2, []); title( ’平滑后图像’ , ’FontWeight’ , ’Bold’ ); end end function I1 = Gray_Convert(I, flag) if nargin < 2 flag = 1 ; end if ndims(I) == 3 I1 = rgb2gray(I); else I1 = I; end if flag figure( 3 ); subplot( 2 , 1 , 1 ); imshow(I, []); title( ’RGB图像’ , ’FontWeight’ , ’Bold’ ); subplot( 2 , 1 , 2 ); imshow(I1, []); title( ’灰度图像’ , ’FontWeight’ , ’Bold’ ); end end function bw2 = Image_Binary(I, flag) if nargin < 2 flag = 1 ; end bw1 = imbinarize(I, graythresh(I)); bw2 = ~bw1; if flag figure( 4 ); subplot( 1 , 3 , 1 ); imshow(I, []); title( ’待处理图像’ , ’FontWeight’ , ’Bold’ ); subplot( 1 , 3 , 2 ); imshow(bw1, []); title( ’二值化图像’ , ’FontWeight’ , ’Bold’ ); subplot( 1 , 3 , 3 ); imshow(bw2, []); title( ’二值化反色图像’ , ’FontWeight’ , ’Bold’ ); end end function [Len, XYn, xy_long] = Hough_Process(bw, Img, flag) if nargin < 3 flag = 1 ; end [H, T, R] = hough(bw); P = houghpeaks(H, 4 , ’threshold’ , ceil( 0 . 3 *max(H( : )))); lines = houghlines(bw, T, R, P, ’FillGap’ , 50 , ’MinLength’ , 7 ); max_len = 0 ; for k = 1 : length(lines) xy = [lines(k).point1; lines(k).point2]; len = norm(lines(k).point1-lines(k).point2); Len(k) = len; if len > max_len max_len = len; xy_long = xy; end XY{k} = xy; % 存储信息 end [Len, ind] = sort(Len( : ), ’descend’ ); % 按长度排序 % 直线信息排序 for i = 1 : length(ind) XYn{i} = XY{ind(i)}; end xy_long = XYn{ 1 }; x = xy_long( : , 1 ); y = xy_long( : , 2 ); if abs(diff(x)) < abs(diff(y)) x = [mean(x); mean(x)]; else y = [ 0 . 7 *y( 1 )+ 0 . 3 *y( 2 ); 0 . 3 *y( 1 )+ 0 . 7 *y( 2 )]; end xy_long = [x y]; if flag figure( 5 ); subplot( 1 , 2 , 1 ); imshow(bw); title( ’二值图像’ , ’FontWeight’ , ’Bold’ ); subplot( 2 , 2 , 2 ); imshow(H, [], ’XData’ , T, ’YData’ , R, ’InitialMagnification’ , ’fit’ ); xlabel( ’ heta’ ); ylabel( ’ho’ ); axis on; axis normal; title( ’霍夫变换域’ , ’FontWeight’ , ’Bold’ ) figure( 6 ); subplot( 1 , 2 , 1 ); imshow(Img); title( ’原图像’ , ’FontWeight’ , ’Bold’ ); subplot( 1 , 2 , 2 ); imshow(Img); title( ’区域标识图像’ , ’FontWeight’ , ’Bold’ ); hold on; plot(xy_long( : , 1 ), xy_long( : , 2 ), ’LineWidth’ , 2 , ’Color’ , ’r’ ); end end function angle = Compute_Angle(xy_long) x1 = xy_long( : , 1 ); y1 = xy_long( : , 2 ); K1 = -(y1( 2 )-y1( 1 ))/(x1( 2 )-x1( 1 )); angle = atan(K1)* 180 /pi; end function [I1, bw1] = Image_Rotate(I, bw, angle, flag) if nargin < 4 flag = 1 ; end I1 = imrotate(I, - 90 -angle, ’bilinear’ ); bw1 = imrotate(bw, - 90 -angle, ’bilinear’ ); if flag figure( 7 ); subplot( 2 , 2 , 1 ); imshow(I, []); title( ’原图像’ , ’FontWeight’ , ’Bold’ ); subplot( 2 , 2 , 3 ); imshow(bw, []); title( ’原二值图像’ , ’FontWeight’ , ’Bold’ ); subplot( 2 , 2 , 2 ); imshow(I1, []); title( ’校正图像’ , ’FontWeight’ , ’Bold’ ); subplot( 2 , 2 , 4 ); imshow(bw1, []); title( ’校正二值图像’ , ’FontWeight’ , ’Bold’ ); end end function [bw2, Loc] = Morph_Process(bw1, flag) if nargin < 2 flag = 1 ; end bw2 = bwareaopen(bw1, round( 0 . 005 *numel(bw1)/ 100 )); bws = sum(bw2); inds = find(bws>round(sum(bw2( : ))* 0 . 015 )); Loc = inds( 1 )- 5 ; bw2( : , Loc: end ) = 0 ; bw2 = bwareaopen(bw2, round( 0 . 005 *numel(bw1)/ 100 )); if flag figure( 8 ); subplot( 1 , 2 , 1 ); imshow(bw1, []); title( ’待操作图像’ , ’FontWeight’ , ’Bold’ ); subplot( 1 , 2 , 2 ); imshow(bw2, []); title( ’滤波图像’ , ’FontWeight’ , ’Bold’ ); end end function [bw1, bw2] = Region_Segmation(XY, bw, Img, flag) if nargin < 4 flag = 1 ; end for i = 1 : 2 xy = XY{i}; XY{i} = [ 1 xy( 1 , 2 ); size(bw, 2 ) xy( 2 , 2 )]; ri(i) = round(mean([xy( 1 , 2 ) xy( 2 , 2 )])); end minr = min(ri); maxr = max(ri); bw1 = bw; bw2 = bw; bw1( 1 :minr+ 5 , : ) = 0 ; bw1(maxr- 5 :end , : ) = 0 ; bw2(minr- 5 :end , : ) = 0 ; bw2( 1 :round (minr* 0 . 5 ), : ) = 0 ; if flag figure( 9 ); subplot( 2 , 2 , 1 ); imshow(Img, []); title( ’原图像’ , ’FontWeight’ , ’Bold’ ); subplot( 2 , 2 , 2 ); imshow(bw, []); title( ’原二值图像’ , ’FontWeight’ , ’Bold’ ); hold on; for i = 1 : 2 xy = XY{i}; plot(xy( : , 1 ), xy( : , 2 ), ’r-’ , ’LineWidth’ , 2 ); end hold off; subplot( 2 , 2 , 3 ); imshow(bw1, []); title( ’下区域图像’ , ’FontWeight’ , ’Bold’ ); subplot( 2 , 2 , 4 ); imshow(bw2, []); title( ’上区域图像’ , ’FontWeight’ , ’Bold’ ); end end function [stats1, stats2, Line] = Location_Label(bw1, bw2, Img, XYn, Loc1, flag) if nargin < 6 flag = 1 ; end [L1, num1] = bwlabel(bw1); stats1 = regionprops(L1); [L2, num2] = bwlabel(bw2); stats2 = regionprops(L2); Line1 = XYn{ 1 }; Line2 = XYn{ 2 }; if mean(Line2( : , 2 )) < mean(Line1( : , 2 )) Line1 = XYn{ 2 }; Line2 = XYn{ 1 }; end [r1, c1] = find(bw1); [r2, c2] = find(bw2); Loc2 = min([min(c1), min(c2)])- 5 ; Line1 = [ 1 mean(Line1( : , 2 )); size(Img, 2 ) mean(Line1( : , 2 ))]; Line2 = [ 1 mean(Line2( : , 2 )); size(Img, 2 ) mean(Line2( : , 2 ))]; Line3 = [Loc2 1 ; Loc2 size(Img, 1 )]; Line4 = [Loc1 1 ; Loc1 size(Img, 1 )]; Line{ 1 } = Line1; Line{ 2 } = Line2; Line{ 3 } = Line3; Line{ 4 } = Line4; if flag figure( 10 ); imshow(Img, []); title( ’标记图像’ , ’FontWeight’ , ’Bold’ ); hold on; for i = 1 : num1 temp = stats1(i).Centroid; plot(temp( 1 ), temp( 2 ), ’r.’ ); end hold off; set(gcf); end end function [Dom, Aom, Answer, Bn] = Analysis(stats1, stats2, Line, Img, flag) if nargin < 5 flag = 1 ; end Line1 = Line{ 1 }; Line2 = Line{ 2 }; Line3 = Line{ 3 }; Line4 = Line{ 4 }; yn1 = round(Line1( 1 , 2 ) + 0 . 18 *(Line2( 1 , 2 )-Line1( 1 , 2 ))); yn2 = round(Line1( 1 , 2 ) + 0 . 34 *(Line2( 1 , 2 )-Line1( 1 , 2 ))); yn3 = round(Line1( 1 , 2 ) + 0 . 50 *(Line2( 1 , 2 )-Line1( 1 , 2 ))); Linen1_1 = [Line1( 1 , 1 ) yn1; Line1( 2 , 1 ) yn1]; Linen2_1 = [Line1( 1 , 1 ) yn2; Line1( 2 , 1 ) yn2]; Linen3_1 = [Line1( 1 , 1 ) yn3; Line1( 2 , 1 ) yn3]; % 定位竖直网格分割线 xn1 = round(Line3( 1 , 1 ) + 0 . 22 *(Line4( 1 , 1 )-Line3( 1 , 1 ))); xn2 = round(Line3( 1 , 1 ) + 0 . 26 *(Line4( 1 , 1 )-Line3( 1 , 1 ))); xn3 = round(Line3( 1 , 1 ) + 0 . 48 *(Line4( 1 , 1 )-Line3( 1 , 1 ))); xn4 = round(Line3( 1 , 1 ) + 0 . 52 *(Line4( 1 , 1 )-Line3( 1 , 1 ))); xn5 = round(Line3( 1 , 1 ) + 0 . 73 *(Line4( 1 , 1 )-Line3( 1 , 1 ))); xn6 = round(Line3( 1 , 1 ) + 0 . 77 *(Line4( 1 , 1 )-Line3( 1 , 1 ))); xn7 = round(Line3( 1 , 1 ) + 0 . 98 *(Line4( 1 , 1 )-Line3( 1 , 1 ))); Linen1_2 = [xn1 Line3( 1 , 2 ); xn1 Line3( 2 , 2 )]; Linen2_2 = [xn2 Line3( 1 , 2 ); xn2 Line3( 2 , 2 )]; Linen3_2 = [xn3 Line3( 1 , 2 ); xn3 Line3( 2 , 2 )]; Linen4_2 = [xn4 Line3( 1 , 2 ); xn4 Line3( 2 , 2 )]; Linen5_2 = [xn5 Line3( 1 , 2 ); xn5 Line3( 2 , 2 )]; Linen6_2 = [xn6 Line3( 1 , 2 ); xn6 Line3( 2 , 2 )]; Linen7_2 = [xn7 Line3( 1 , 2 ); xn7 Line3( 2 , 2 )]; ym1_1 = round(Line1( 1 , 2 ) + 0 . 32 *(Linen1_1( 1 , 2 )-Line1( 1 , 2 ))); ym2_1 = round(Line1( 1 , 2 ) + 0 . 5 *(Linen1_1( 1 , 2 )-Line1( 1 , 2 ))); end

3 仿真结果

4 参考文献

[1]罗朝阳, 张鹏超, 姚晋晋,等. 基于Hough变换的答题卡识别[J]. 计算机应用与软件, 2020, 37(3):6.

博主简介:擅长智能优化算法、神经网络预测、信号处理、元胞自动机、图像处理、路径规划、无人机等多种领域的Matlab仿真,相关matlab代码问题可私信交流。

部分理论引用网络文献,若有侵权联系博主删除。

版权:如无特殊注明,文章转载自网络,侵权请联系cnmhg168#163.com删除!文件均为网友上传,仅供研究和学习使用,务必24小时内删除。
相关推荐