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

网友投稿 233 2022-09-08


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

1 简介

本文实现一个基于MATLAB的答题卡识别。MATLAB是一款商业数学软件,可用于科学计算和工程绘图,具有相应的功能函数,可以对图像进行标注和打印,还可以对指定的图像处理光照、色度等。而基于MATLAB的答题卡处理,首先,对答题卡进行归一化、平滑处理、灰度化、二值化的预处理,再运用MATALB中的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;endif size(I, 1) > 2000 I = imresize(I, 0.2, 'bilinear');endI1 = 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');endendfunction I2 = Image_Smooth(I1, hsize, sigma, flag)if nargin < 4 flag = 1;endif nargin < 2 hsize = [3 3]; sigma = 0.5;endh = 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');endendfunction I1 = Gray_Convert(I, flag)if nargin < 2 flag = 1;endif ndims(I) == 3 I1 = rgb2gray(I);else I1 = I;endif flag figure(3); subplot(2, 1, 1); imshow(I, []); title('RGB图像', 'FontWeight', 'Bold'); subplot(2, 1, 2); imshow(I1, []); title('灰度图像', 'FontWeight', 'Bold');endendfunction bw2 = Image_Binary(I, flag)if nargin < 2 flag = 1;endbw1 = 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');endendfunction [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)};endxy_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)];endxy_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('\theta'); ylabel('\rho'); 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');endendfunction 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;endfunction [I1, bw1] = Image_Rotate(I, bw, angle, flag)if nargin < 4 flag = 1;endI1 = 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');endendfunction [bw2, Loc] = Morph_Process(bw1, flag)if nargin < 2 flag = 1;endbw2 = 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');endendfunction [bw1, bw2] = Region_Segmation(XY, bw, Img, flag)if nargin < 4 flag = 1; endfor 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)]));endminr = 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');endendfunction [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);endendfunction [Dom, Aom, Answer, Bn] = Analysis(stats1, stats2, Line, Img, flag)if nargin < 5 flag = 1;endLine1 = 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代码问题可私信交流。

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


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:matplotlib.pyplot绘图中文乱码解决办法(python matplotlib.pyplot报错)
下一篇:【水果分级】基于计算机视觉实现苹果分级系统含Matlab源码(基于matlab的水果分级设计)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~