您的位置:首页 > 其它

影像之结构化特征

2015-11-02 14:56 218 查看
【问题描述】

在影像比对中,有一种方法是利用影像中的边缘(edge)资讯,计算每个边缘资讯中具有代表性的结构化特征,以作为比对两张影像是否相似的判断标准。Water-filling方法是从每个边缘图的一个端点开始,绕着相连的边缘点走并依序编号。若走到某一步时,遇到一个以上不同的连接点,则分成不同路径同时继续走,直到没有任何连接点为止。如果一个点和另一个点为上下左右相邻,就称为连接。

例如,在图1的影像中包含三个边缘图,每个边缘图由一些互相连接的边缘点构成。图中以黑色的方块代表边缘点,白色的方块代表背景。在Water-filling方法中,首先,从第一列(row)开始,由左至右,由上至下,先找到第一个黑点并编号为1。接着,找1的下一个尚未编号的连接点并编号为2。依此方法继续往下一个点前进依次编号。在编号6的点之后有两个尚未编号的连接点,此时,则分为两条路线,并同时编号为7继续往下走。当走到没有任何的相连点时,则结束现有边缘图的编号,并继续对影像中的其它边缘图编号。走完图1所有边缘图后所得到的编号如图2所示。所以,走完这三个边缘图所需要的步数分别为12、7及3;所以,12、7及3可以作为代表此张影像的结构化特征。请注意:位于斜对角上的两点不能算做连接,如:

请写一个程序计算每个影像中,以Water-filling方法走完其中所有的边缘图后,将每个边缘图需走的步数依走访的顺序列出。

【输入说明】

输入文件包含一个正方形的影像。每组影像以图的宽度n开头(l≤n≤1000)。接下来的n行代表影像的内容:0表示背景的白点,1表示黑色的边缘点。

【输出说明】

对每一个输入的影像,以Water-filling方法走完所有的边缘图后,先印出此张影像中共有几个边缘图。接着,将每个边缘图需走的步数按升序列出。

【样例输入】

10

0000000000

0011110000

0000010000

0011111000

0010110100

0010010110

0011110010

0100010010

0100000110

0100000000

【样例输出】

3

3

7

12

思路:宽搜(BFS)。从左至右,从上至下,扫描整个矩形,当遇到一个没有填充的边缘点时,从这点开始进行广搜操作,填充所有相邻的边缘点,直到广搜停止。然后统计当前广搜的步数,就是这个边缘图需要走的步数。再将所有步数储存下来,进行快排,输出。

program t2;
const
fx:array[1..4] of longint=(1,-1,0,0);
fy:array[1..4] of longint=(0,0,-1,1);
var f,dt:array[0..1001,0..1001] of longint;
i,j,n,max,sum,flag,k,h,t:longint;
ans,bx,by:array[0..1000000] of longint;
s:ansistring;
pd:array[0..1000,0..1000] of boolean;
procedure sort(l,r: longint);//快排,用来排边缘图的步数
var
i,j,x,y: longint;
begin
i:=l;
j:=r;
x:=ans[(l+r) div 2];
repeat
while ans[i]<x do
inc(i);
while x<ans[j] do
dec(j);
if not(i>j) then
begin
y:=ans[i];
ans[i]:=ans[j];
ans[j]:=y;
inc(i);
j:=j-1;
end;
until i>j;
if l<j then
sort(l,j);
if i<r then
sort(i,r);
end;
function bfs:longint;
var max,x,y:longint;
begin
max:=0;
while h<t do//还未搜完
begin
inc(h);
x:=bx[h];
y:=by[h];
if f[x,y]>max then max:=f[x,y];
for k:=1 to 4 do//搜索上下左右四个方向(存在先后)
begin
if (f[x+fx[k],y+fy[k]]=0)and(dt[x+fx[k],y+fy[k]]=1) then
//如果找到的点没走过并且可以走的话
begin//那就标记成已走过,并增加步数的值
inc(t);
bx[t]:=x+fx[k];
by[t]:=y+fy[k];
f[x+fx[k],y+fy[k]]:=f[x,y]+1;
end;
end;
end;
exit(max);
end;
begin
fillchar(pd,sizeof(pd),true);
readln(n);
for i:=1 to n do
begin
readln(s);
for j:=1 to n do
begin
dt[i,j]:=ord(s[j])-48;
if dt[i,j]=1 then pd[i,j]:=false;
end;
end;
for j:=1 to n do
for i:=1 to n do
if  (f[i,j]=0)  and (dt[i,j]<>0)then
begin
t:=1; h:=0;
f[i,j]:=1;
bx[t]:=i; by[t]:=j;
inc(sum);
ans[sum]:=bfs;
end;
sort(1,sum);
writeln(sum);
for i:=1 to sum do writeln(ans[i]);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: