1. 程式人生 > 其它 >【答題卡識別】基於matlab形態學答題卡識別【含Matlab原始碼 1135期】

【答題卡識別】基於matlab形態學答題卡識別【含Matlab原始碼 1135期】

一、簡介

1 概述
1.1 基本思想

用具有一定形態的結構元素去度量和提取影象中的對應形狀,以達到對影象分析和識別的目的

1.2 基本運算
膨脹、腐蝕、開操作、閉操作

1.3 數學基礎
集合論

結構元素:

原始影象需要擴充使得結構元素位於原始影象邊緣時擴充部分可以涵蓋整個結構元素。

2 二值影象形態學基本操作
2.1 腐蝕操作

結構元素B全部位於A中對應的位移量z,故會削弱邊界

效果:

是一種收縮或細化的操作。

2.1 膨脹操作
結構元素B與A有交集對應的位移量z,故會擴張邊界

效果:

是一種增長或粗化的操作。
注:腐蝕和膨脹是對偶的(即對前景腐蝕後求反=對背景膨脹的結果)

2.3 開操作


先腐蝕後膨脹,平滑物體的輪廓,斷開較窄的連線條、消除細的突出物


2.4 閉操作
先膨脹後腐蝕,同樣能平滑物體的輪廓,但會彌合較窄的間斷和細長條

效果:向外的角保持不變,向內的角變圓了,填補間斷—“加”

2.5 開操作和閉操作的比較
2.5.1 對偶性(閉操作後取反結果=對背景開操作)

2.5.2 性質
運算元應用一次後,再用則無變化

2.5.3 對比效果

2.5.4 應用
開操作取出影象中的小目標(去噪)
閉操作連線目標(消除細小間隔)

2.6 擊中擊不中變換
目的:形狀檢測(檢測某種特定形狀的位置,要求每個物體至少被一個畫素寬的背景所圍繞)
將前景和背景一起匹配


3 二值影象形態學演算法


3.1 邊界提取

前景-被腐蝕的前景

3.2 孔洞填充

找一個起始點(位於孔洞中),不停膨脹後並上A反,直到不再發生變化

3.3 聯通分量的提取

通過上述迭代公式可以從聯通圖案的一個已知點得到整個聯通圖案

3.4 凸殼
凸:集合A內連線任意兩個點的連線都在A內,則稱集合A是凸的
凸殼:任意集合S的凸殼H是包含於S的最小凸集

其中X0為A,Bi是不同方位的結構元素,一個Bi能夠做出一個Di,A的凸殼為所有的Di相交


結果:

3.5 細化
A減去A與結構元B做擊中擊不中變換匹配到的那部分畫素

其中B為結構元序列


步驟:
A被B1~Bn按次序細化,再返回B1,從B1開始按次序細化,直到收斂

3.6 粗化


細化的形態學對偶
A並上A與結構元B做擊中擊不中變換匹配到的那部分畫素的和


3.7 骨架
A的骨架可用腐蝕和開操作表達

其中k代表對A進行k次腐蝕,而K則是A被腐蝕為空集前最後一次迭代

3.8 剪裁
是對細化處理和骨架繪製演算法的補充,因為這些處理會將附加部分保留下來,應清楚乾淨,則需要剪裁來取出寄生的多餘部分

4 灰度級形態學
4.1 操作
腐蝕:輸出影象變暗,亮的細節被減少
膨脹:輸出影象變亮,暗的細節被減少
4.2 效果

開操作:去除較小的明亮細節
閉操作:去除較小的暗細節

4.3 演算法
影象平滑:先開(抑制亮細節)後閉(抑制暗細節)
形態學梯度:膨脹-腐蝕
頂帽變換:校正不均勻光照,增強陰影的細節

二、原始碼

clc;clear;close;
A=imread('datika.jpg');%讀取影象
imshow(A),title('原圖');
gray=rgb2gray(A);
bw=edge(gray,'canny');%canny運算元邊緣檢測得到二值邊緣影象
[h,t,r]=hough(bw,'RhoResolution',0.5,'ThetaResolution',0.5);                %Hough變換
figure,imshow(imadjust(mat2gray(h)),'XData',t,'YData',r,'InitialMagnification','fit'),title('Hough變換矩陣');%顯示Hough變換矩陣
xlabel('\theta'),ylabel('\rho');
axis on, axis normal,hold on;
P=houghpeaks(h,2);
x=t(P(:,2));y=r(P(:,1));
plot(x,y,'s','color','r'),title('');%獲取並標出引數平面的峰值點
lines=houghlines(bw,t,r,P,'FillGap',5,'Minlength',7);%檢測影象中的直線段
figure,imshow(gray);
hold on;
max_len=0;
for i=1:length(lines)
    xy=[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');%標註直線段端點
end

% x=lines.theta;%由與影象邊緣平行的直線段的斜率得到整個影象旋轉的角度
% B=imrotate(gray,x);%影象修正
% figure,imshow(B),title('旋轉後圖像');


T=graythresh(gray);%使用OTSU方法獲得閥值T
result=im2bw(gray,T);%二值化影象
figure,imshow(result),title('二值化後結果');

%掃描區域:在本程式中,有7個掃描區域,分別對應題號為1-5,6-10,11-15,16-20,21-25,26-30,31-35這幾個區域
n=40;m=530;% 首先測得答題區域第一題A選項左上角的座標(52,244)
s=150;t=228;%s為上下兩個掃描區域的距離,t為左右兩個掃描區域的距離。
P=4;Q=5;%P為字母項的個數(這裡有ABCD共有4項),Q為每個小區域選項數。
interval_length=35;%左右相鄰兩題填塗區域左邊線的距離
interval_width=25;%上下相鄰兩題填塗區域上邊線的距離
length=23;%填塗區域的長度
width=11;%填塗區域的寬度
a2=zeros(4,5);%初始化灰度值統計矩陣
a3=zeros(10,9);%學號 初始化灰度值統計矩陣

%第1-5題區域的檢測
for P=1:4
    for Q=1:5
        %m=244;n=52;%第1-5題區域的檢測的起始座標(即第一題A選項左上角的座標)
        a1=result(m+(P-1)*(interval_width+1) :m+(P-1)*(interval_width+1)+width,n+(Q-1)*(interval_length+1):n+(Q-1)*(interval_length+1)+length);
        %得到矩形區域內各畫素的灰度值
        sum1=sum(sum(a1));%計算統計的矩形區域內畫素灰度值之和
        a2(P,Q)=sum1;%多次迴圈後得到20個統計區域的灰度值,並依次放在a2矩陣中

    end
end       


a2(a2<224)=1;
a2(a2>=225)=0;%對灰度值統計矩陣裡的數值進行處理,大於某一閥值的值賦1,其餘的賦0。
             %在此程式中,塗黑則相應數值為1。
result1_5=a2;%儲存1-5題的結果

%第6-10題區域的檢測
for P=1:4
    for Q=1:5
        a1=result(m+s*1+(P-1)*(interval_width+1) :m+s*1+(P-1)*(interval_width+1)+width,n+(Q-1)*(interval_length+1):n+(Q-1)*(interval_length+1)+length);
        sum1=sum(sum(a1));
        a2(P,Q)=sum1;

    end
end       

a2(a2<180)=1;
a2(a2>=181)=0;
result6_10=a2; %儲存6-10題的結果

%第11-15題區域的檢測
for P=1:4
    for Q=1:5
        a1=result(m+(P-1)*(interval_width+1) :m+(P-1)*(interval_width+1)+width,n+t*1+(Q-1)*(interval_length+1):n+t*1+(Q-1)*(interval_length+1)+length);
        sum1=sum(sum(a1));
        a2(P,Q)=sum1;

    end
end     
a2(a2<224)=1;
a2(a2>=225)=0;
result11_15=a2; %儲存11-15題的結果

%第16-20題區域的檢測
for P=1:4
    for Q=1:5
        a1=result(m+s*1+(P-1)*(interval_width+1) :m+s*1+(P-1)*(interval_width+1)+width,n+t*1+(Q-1)*(interval_length+1):n+t*1+(Q-1)*(interval_length+1)+length);
        sum1=sum(sum(a1));
        a2(P,Q)=sum1;

    end
end   

a2(a2<240)=1;
a2(a2>=241)=0;
result16_20=a2; %儲存16-20題的結果

%第21-25題區域的檢測
for P=1:4
    for Q=1:5
        a1=result(m+s*2+(P-1)*(interval_width+1) :m+s*2+(P-1)*(interval_width+1)+width,n+t*1+(Q-1)*(interval_length+1):n+t*1+(Q-1)*(interval_length+1)+length);
        sum1=sum(sum(a1));
        a2(P,Q)=sum1;

    end
end   

a2(a2<200)=1;
a2(a2>=201)=0;
result21_25=a2; %儲存21-25題的結果

%第26-30題區域的檢測
for P=1:4
    for Q=1:5
       a1=result(m+s*3+(P-1)*(interval_width+1) :m+s*3+(P-1)*(interval_width+1)+width,n+t*1+(Q-1)*(interval_length+1):n+t*1+(Q-1)*(interval_length+1)+length);
        sum1=sum(sum(a1));
        a2(P,Q)=sum1;

    end
end   

a2(a2<224)=1;
a2(a2>=225)=0;
result26_30=a2; %儲存26-30題的結果

% %第31-35題區域的檢測
% for P=1:4
%     for Q=1:5
%        a1=result(m+s*4+(P-1)*(interval_width+1) :m+s*4+(P-1)*(interval_width+1)+width,n+t*1+(Q-1)*(interval_length+1):n+t*1+(Q-1)*(interval_length+1)+length);
%         sum1=sum(sum(a1));
%         a2(P,Q)=sum1;
% 
%     end

三、執行結果






四、備註

版本:2014a

完整程式碼或代寫加QQ1564658423