1 Star 1 Fork 0

小小 / 机读卡答案识别-matlab

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
XuanZe3.m 9.87 KB
一键复制 编辑 原始数据 按行查看 历史
小小 提交于 2018-02-28 21:20 . Upload XuanZe3.m
%function XuanZe3
clc;%清除命令行
close all;%关闭figure
clear;%清除变量
%%
I = imread('chongying.jpg');%重影
% I = imread('jiaozang.jpg');%较脏
if size(I,3) > 1 % 维度 ndims(I) > 2
I = rgb2gray(I);
end
I = im2double(I);
%%
%二值化 - 第一天
avgI = averagefilter(I, floor(size(I)/16)*2+1, 'replicate');
I_s = 1 - avgI + I;%
I_s = I_s.^16;%一定要用0-1之间的灰度
%I_s=I_s/2;
BW = im2bw(I_s,graythresh(I_s));%im2bw
BW = ~BW;
figure('name','原图二值化'),imshow(BW);
%%
%ROI定位 - 第二天
% %求取边缘
%%
%提取直线
bws = BW;
%%
%寻找harris角点
L1 = bwlabel(BW);
S1 = regionprops(L1,'BoundingBox');
max_area = 0;
for i = 1:length(S1)
area = S1(i).BoundingBox(3)*S1(i).BoundingBox(4);
if area>max_area
max_area = area;
pos = i;
end
end
ROIbw = (L1 == pos);
% figure(),imshow(ROIbw);
corners = detectHarrisFeatures(ROIbw);
figure('name','harris候选点'),imshow(I); hold on;
plot(corners.selectStrongest(79));hold off % 8
hc = corners.selectStrongest(6);
hcxy = hc.Location;
% hcxy = pselect;
loccir = mean(hcxy);
dis = (hcxy(:,1)-loccir(1)).^2+(hcxy(:,2)-loccir(2)).^2;
[dissort,idx] = sort(dis);
ROIpoints = hcxy(idx(end-3:end),:);
figure('name','确定角点'),imshow(I); hold on;
plot(ROIpoints(:,1),ROIpoints(:,2),'r+');hold off;
%%
%根据最大外界矩形框确定范围
%已经得到最大标号 pos
%%
%选择题识别 - 第三天
%R=A/B=inv(A)*B;B=A*R;
disxy(:,1) = ROIpoints(:,1)-loccir(1);
disxy(:,2) = ROIpoints(:,2)-loccir(2);
disflag = disxy<0;
ind = xor(disflag(:,1),disflag(:,2))+disflag(:,2)*2+1;
ROIpoints = ROIpoints(ind,:);
Roibw = roipoly(I,[ROIpoints(:,1);ROIpoints(1,1)],...
[ROIpoints(:,2);ROIpoints(1,2)]);
RoiImage = I .* Roibw;
figure('name','ROI 待识别区域'),imshow(RoiImage)
%四个原顶点
x = ROIpoints(:,2);
y = ROIpoints(:,1);
width = round(max(x)-min(x));
height= round(max(y)-min(y));
%校正后的顶点
Y(1) = y(1); Y(4)=y(1);Y(2:3)=Y(1)+height;
X(1:2)= x(1);X(3:4)=X(1)-width;
tform = fitgeotrans(ROIpoints,[Y' X'],'similarity');%similarity Projective
% [newy,newx] = transformPointsForward(tform,ROIpoints(:,1),ROIpoints(:,2));
% del=[newy,newx]-[Y' X'];
Is = imwarp(I,tform); %应用变换,将图像旋转 I为灰度图像,不能二值图
Iover=imfuse(I,Is);
figure('name','应用变换-校正'),imshow(Iover);
%Is = imwarp(RoiImage,tform);
Is = imwarp(bws,tform); %会有空洞
figure('name','校正-图像'),imshow(Is);
%%
%选择题识别
%框出选择题区域
%二值化
%定位选项中心
%中心所处位置-转换为选项答案
%得到校正二值化图像 Is
%求取边缘
Ie=edge(Is,'canny');
S1 = regionprops(Ie,'BoundingBox','PixelIdxList');
max_area = 0;
for i = 1:length(S1)
area = S1(i).BoundingBox(3)*S1(i).BoundingBox(4);
if area>max_area
max_area = area;
pos = i;
end
end
bbox = S1(pos).BoundingBox;
I1 = zeros(size(Is));
I1(bbox(2):bbox(2)+bbox(4),bbox(1):bbox(1)+bbox(3)) = Is(bbox(2):bbox(2)+bbox(4),bbox(1):bbox(1)+bbox(3));
figure('name','校正后 - 提取区域结果'),imshow(I1);%小数
%%
%定位选择题区域
% lines=houghlines(bws,theta,rho,P,'FillGap',5,'MinLength',7);
[H, T, R] = hough(I1);
P = houghpeaks(H, 5);
lines = houghlines(I1, 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}; %1 - 2
[h w] = size(I1);
if(xy_long(1,2) > h/2)
xy_long = XYn{2};
end
% 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];
% figure('units', 'normalized', 'position', [0 0 1 1]);
figure('name','选择题区域');
subplot(1, 2, 1); imshow(I); title('原图像');
subplot(1, 2, 2); imshow(I); title('选择题区域标识图像');
hold on;
plot(xy_long(:,1), xy_long(:,2), 'LineWidth', 2, 'Color', 'r');
hold off;
%向下加120
%区域范围
%%
bw1 = I1;
% imwrite(bw1,'wait.jpg','jpg');
%BW2 = bwareaopen(BW,P,conn)
%删除二值图像BW中面积小于P的对象,默认情况下conn使用8邻域。
% 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));
bw2 = bw1;
x1 = xy_long(2,2) + 5;
x2 = x1 + 115;
y1 = xy_long(1,1);
y2 = xy_long(2,1);
bw2(1:x1,:) = 0;
bw2(x2:end,:) = 0;
bw2 = bwareaopen(bw2,50);%过滤面积小于50的内容 50 - 70
bw2 = bw2 - bwareaopen(bw2,75);%过滤面积大于70的内容
% figure,imshow(bw2);
figure('name','过滤小面积干扰');
subplot(1, 2, 1); imshow(bw1); title('带操作图像');
subplot(1, 2, 2); imshow(bw2); title('过滤小面积后图像');
bw3 = imcrop(bw2,[y1,x1,abs(y2-y1),abs(x2 -x1)]);
%定位选项中心
L = bwlabel(bw3);%连通域标号
stats = regionprops(L, 'Centroid');
figure('name','定位中心'),imshow(L);
hold on;
%画网格 116*346
%106 * 346
% bw3=imresize(bw3,[106,346]);
[im_h, im_w] = size(L);
%间隔x_w划
x_w = floor(im_w / 20);%17
x_h = floor(im_h / 14);%8
[gridX1,gridY1] = meshgrid(1:x_w:im_w,1:x_w:im_w);
[gridY2,gridX2] = meshgrid(1:x_h:im_w, 1:x_h:im_w);
plot(gridX2,gridY2,'g');
plot(gridX1,gridY1,'r');
for i = 1 : length(stats)
temp = stats(i).Centroid;
plot(temp(1), temp(2), 'r.');
col = floor((temp(1)-1)/x_w + 1);%列
option = mod(col,5);%ABCD
if option == 0
option = 4;
else
option = option - 1;
end
row = floor((temp(2)-1)/x_h + 1);%行
if row > 7
row = row - 2;
else
row = row - 1;
if row == 6
row = 5;
end
end
onum = floor(row + floor((col-1)/5)*10);%题号
result(onum) = option;
% tak = floor((temp(1)-33) ./ 18 + 1); %列
% ta = floor(mod(tak,6));%ABCD
% tnumk = floor((temp(2)-162) ./ 8+1);%行
% tnum = floor(tnumk + int32(tak./5) * 10);%题号
end
hold off;
%将选项答案宝存入文件
%答案存入文件中
fid = fopen('result.txt','w');
for i = 1:length(result)
fprintf(fid,'%d',i);
fprintf(fid,'%s','题 : ');
switch result(i)
case 1
sele = 'A';
case 2
sele = 'B';
case 3
sele = 'C';
case 4
sele = 'D';
otherwise
sele = '读取错误';
end
fprintf(fid,'%s \r\n',sele);
end
fclose(fid);
% hold on;
% plot(Linem1_1(:, 1), Linem1_1(:, 2), 'r-', 'LineWidth', 1);
%(33,162) - (33,246) 间隔8 共11个横 33 -51 -68 -86 间隔18 共19个纵
%%
%SVM - 第四天
%数字识别
%svmtrain和svmclassify
%%
%大致确定数字区域
xy_second = XYn{2};%第二长的线 2 - 3
if(xy_second(2,2) > 100)
xy_second = XYn{3};
end
% bw_num = bw1;
%向下+70
figure('name','数字区域');
subplot(1, 2, 1); imshow(I); title('原图像');
subplot(1, 2, 2); imshow(I); title('数字区域标识图像');
hold on;
plot(xy_second(:,1), xy_second(:,2), 'LineWidth', 2, 'Color', 'r');
hold off;
num_x1 = xy_second(2,2)+5;
num_x2 = num_x1 + 65;
num_y1 = xy_second(1,1);
num_y2 = xy_second(2,1);
bw_num = imcrop(bw1,[num_y1,num_x1,abs(num_y2-num_y1),abs(num_x2 -num_x1)]);
% bw_num(1:num_x1,:) = 0;
% bw_num(num_x2:end,:) = 0;
bw_num = bwareaopen(bw_num,30);%过滤面积小于50的内容 50 - 70
% bw2 = bw2 - bwareaopen(bw1,75);%过滤面积大于70的内容
figure('name','大致确定数字区域'),imshow(bw_num);
%%
%最大连通域确定数字区域
BW = bw_num;
L1 = bwlabel(BW);
S1 = regionprops(L1,'BoundingBox');
max_area = 0;
for i = 1:length(S1)
area = S1(i).BoundingBox(3)*S1(i).BoundingBox(4);
if area>max_area
max_area = area;
pos = i;
end
end
ROIbw = (L1 == pos);
%根据最大外界矩形框确定范围
%已经得到最大标号 pos
NUMpoints(1,1) = S1(pos).BoundingBox(1);
NUMpoints(1,2) = S1(pos).BoundingBox(2);
NUMpoints(2,1) = S1(pos).BoundingBox(1) + S1(pos).BoundingBox(3);
NUMpoints(2,2) = S1(pos).BoundingBox(2);
NUMpoints(3,1) = S1(pos).BoundingBox(1);
NUMpoints(3,2) = S1(pos).BoundingBox(2) + S1(pos).BoundingBox(4);
NUMpoints(4,1) = S1(pos).BoundingBox(1) + S1(pos).BoundingBox(3);
NUMpoints(4,2) = S1(pos).BoundingBox(2) + S1(pos).BoundingBox(4);
figure('name','确定角点'),imshow(bw_num); hold on;
plot(NUMpoints(:,1),NUMpoints(:,2),'r+');hold off;
% figure(),imshow(ROIbw);
%%
% corners = detectHarrisFeatures(ROIbw);
% figure('name','harris候选点'),imshow(bw_num); hold on;
% plot(corners.selectStrongest(38));hold off % 8
%
% hc = corners.selectStrongest(25);%25
% hcxy = hc.Location;
% loccir = mean(hcxy);
% dis = (hcxy(:,1)-loccir(1)).^2+(hcxy(:,2)-loccir(2)).^2;
% [dissort,idx] = sort(dis);
% NUMpoints = hcxy(idx(end-3:end),:);
% figure('name','确定角点'),imshow(bw_num); hold on;
% plot(NUMpoints(:,1),NUMpoints(:,2),'r+');hold off;
num_x = NUMpoints(1,1);
if NUMpoints(1,2) > NUMpoints(2,2)
num_y = NUMpoints(2,2);
else
num_y = NUMpoints(1,2);
end
num_w = abs(NUMpoints(1,2) - NUMpoints(2,2));
num_h = abs(NUMpoints(1,1) - NUMpoints(3,1));
if num_w == 0
num_w = abs(NUMpoints(1,2) - NUMpoints(3,2));
num_h = abs(NUMpoints(1,1) - NUMpoints(2,1));
end
bw_num = imcrop(bw_num,[num_x,num_y,num_h,num_w]);
figure('name','最终数字图片'),imshow(bw_num);
%%
%切割数字图片并保存下来
[m n] = size(bw_num);
num_width = n/11;
L = bwlabel(bw_num);%连通域标号
% for i = 1:11
% s = sprintf('digittest/num/num(%d).jpg',i);
% img_num = imcrop(bw_num,[1+num_width*(i-1),1,num_width,m]);
% imwrite(~img_num,s,'jpg');
% end
S1 = regionprops(L,'BoundingBox');
for i = 2:length(S1)
s = sprintf('digittest/num/num(%d).jpg',i-1);
img_num = imcrop(bw_num,S1(i).BoundingBox);
imwrite(~img_num,s,'jpg');
end
%%
%SVM数字识别
%svm训练 - 分类
[labelp,classp] = digital();
Matlab
1
https://gitee.com/xx2018/machine_read_card_answer_recognition_matlab.git
git@gitee.com:xx2018/machine_read_card_answer_recognition_matlab.git
xx2018
machine_read_card_answer_recognition_matlab
机读卡答案识别-matlab
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891