?? p0802.m
字號:
I=imread('19-3-02.jpg');
%I=imread('49-3-BW01.jpg');
I=im2bw(I,0.43);
[y x]=size(I);
Top=zeros(1,x); % 頂端輪廓檢測
for i=1:x
j=1;
while ((I(j,i)==1)&&(j<y))
j=j+1;
end
Top(i)=y-j;
end
Bottom=zeros(1,x); % 底部輪廓檢測
for i=1:x
j=y;
while ((I(j,i)==1)&&(j>1))
j=j-1;
end
Bottom(i)=y-j;
end
Height=Top-Bottom;
WordHeight=max(Height); % 文字高度
%=== 輪廓線的凹檢測 ===%
TopD=zeros(1,x-1);
Concave=1; % 記錄凹輪廓處的位置, 1表示默認起始列為第一個Concave
Deep=0; % 下降值
DeepH=0; % 上升值
DeepT=5; % 凹輪廓的深度閾值
Sign=0;
for i=1:x-1
TopD(i)=Top(i+1)-Top(i);
end
for i=1:x-2
if (TopD(i)<0) % 判斷是否為凹輪廓
Sign=1; % 置標志位
DeepH=0;
Deep=Deep+TopD(i);
tempX=i+1; % 下一列可能為切分的Concave, 最接近于左端
end
if ((Sign==1)&&(TopD(i)>0))
if (abs(Deep)>=DeepT)
DeepH=DeepH+TopD(i);
if (abs(DeepH)>=DeepT)
Concave=[Concave tempX];
Sign=0; % 確認為凹后,復位標志位
DeepH=0;
end
else
Sign=0; % 確認為凹后,復位標志位
Deep=0;
end
end
end
%=== 輪廓線的凸檢測 ===%
BottomD=zeros(1,x-1);
Convex=1;
Asend=0; % 上升值
Desend=0; % 下降值
ConvexT=3; % 凸程度閾值
Sign=0;
for i=1:x-1
BottomD(i)=Bottom(i+1)-Bottom(i);
end
for i=1:x-2
if (BottomD(i)>0)
Sign=1;
Desend=0;
Asend=Asend+BottomD(i);
tempX=i+1; % 最接近于左端
end
if((Sign==1)&&(BottomD(i)<0))
if (abs(Asend)>=ConvexT)
Desend=Desend+BottomD(i);
if (abs(Desend)>=ConvexT)
Convex=[Convex tempX];
Sign=0; % 復位
Desend=0;
end
else
Sign=0; % 復位
Asend=0;
end
end
end
%=== 切分 ===%
[mytemp n]=size(Concave); % 注意 Concave 的第一個數值無效
StrokeT=5; % 筆劃寬度閾值
GapT=8;
W=zeros(1,n);
for i=1:n-1
W(i)=Concave(i+1)-Concave(i);
end
W(n)=x-Concave(n);
Width=median(W); % 近似的字符寬度
PXR1=1; % 記錄第一次切分位置
PXR2=1; % 記錄第二次切分位置
Mark=0; % 記錄黑白轉換的次數
%CrossSign=0; % 交錯粘連的標志
Black=zeros(1,x); % 統計筆劃像素點
BP=zeros(1,x);
SegSoke=zeros(3,x); % 切分點處的筆劃寬度
RH=zeros(1,x); % 切分后的高度比
RW=zeros(1,x); % 切分后的寬度比
Score=zeros(1,x); % 特征值的總得分
XGood=1; % X切分位置
SegY=1; % 記錄第一次切分的Y深度
for k=2:n
WordH=max(Height(Concave(k-1):Concave(k)));
WordW=Concave(k)-Concave(k-1);
if ((WordW>=0.5*Width)&&(WordW<=1.5*Width))
% 選定切分的區域
PX1=Concave(k);
PX2=PX1;
while ((TopD(PX2)==0)&&(PX2<x))
PX2=PX2+1; % 凹右邊的列位置
end
i=fix((PX1+PX2)/2);
if (Top(i)==1) % 無粘連
PXR1=[PXR1 i];
PXR2=[PXR2 i];
else
j=y+1-Top(i); % PY為實際的y坐標值,此處已為黑色像素點
Mark=0;
while((j<y)&&(Mark<2))
if (I(j,i)==0)
Black(i)=Black(i)+1; % 記錄黑色象素點數
Si=i;
while ((Si>1)&&(I(j,Si)==0)) % 左筆劃寬度
Si=Si-1;
SegSoke(1,i)=SegSoke(1,i)+1;
end
Si=i;
while ((Si<x)&&(I(j,Si)==0)) % 右筆劃寬度
Si=Si+1;
SegSoke(2,i)=SegSoke(2,i)+1;
end
end
Mark=Mark+abs(I(j+1,i)-I(j,i)); % 檢測是否通過筆劃
j=j+1;
end
SegY=[SegY j-1]; % 第一次切分截止處
if (j==38)
PXR1=[PXR1 i];
PXR2=[PXR2 i];
else % 單點粘連
SLi=i;
while ((SLi>1)&&(I(j-1,SLi)==1)) % 選定區域左邊界
SLi=SLi-1;
end
SRi=i;
while ((SRi<x)&&(I(j-1,SRi)==1)) % 選定區域右邊界
SRi=SRi+1;
end
[Mytemp PX2]=max(Bottom(SLi:SRi));
PXR2=[PXR2 PX2+SLi-1];
PXR1=[PXR1 i];
end
end
else if (WordW>1.5*Width)
PX=fix((Concave(k)+Concave(k-1))/2); % 避免水平“橫”的粘連
k=k-1;
end
% 如果寬度過小,則不切分
end
end
%==== Segment ===%
for i=2:n
WI=I(:,fix((PXR1(i-1)+PXR2(i-1))/2):fix((PXR1(i)+PXR2(i))/2));
figure(10+i);imshow(WI);
end
WI=I(:,fix((PXR1(i)+PXR2(i))/2):x);
figure(10+i+1);imshow(WI);
%=== 圖像顯示 ===%
px=(1:x); % X軸坐標
figure(1);
imshow(I);
figure(2);
plot(Top);hold on
plot(px,y,'red');grid
title('上輪廓');
figure(3);
plot(Bottom);hold on
plot(px,y,'red');grid
title('下輪廓');
figure(4);
plot(Height);grid
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -