图像轮廓代表图像特征的线要素。在提取轮廓时,首先应当注重于浓度的变化。
图像的浓度急剧变化,称之为边界。提取出清晰漂亮的轮廓并非易事,不过有很多算法可以实现。
2.1 利用微分提取图像的轮廓。
由于轮廓产生于浓度值急剧变化的部分,因此可知,利用可以取出函数变化部分的微分运算就能抽出图像的轮廓。而微分又有一阶微分(斜率)与二阶微分(拉普拉斯算子),这两种微分可用于轮廓的提取。
(1)一阶微分(斜率,差分)
在x方向上的微分为 fx=f(x+1,y)-f(x,y)
在y方向上的微分为 fy=f(x,y+1)-f(x,y)
强度为fx和fy的平方和的开方根
或者为|fx|+|fy|
方向为(fx,fy)
求解公式是,第二条简单,但是,由轮廓浓度较暗处指向较明处。可以从梯度满意的检测出边界。
(2)二阶微分(拉普拉斯算子)
拉普拉斯算子又称为二阶微分L(x,y) 。由于他是把梯度,变化率再求一次微分,所以只用求出轮廓的强度(不求方向)。
数字图像以下式表示:
L(x,y)=4Xf(x,y)-{f(x,y-1)+f(x,y+1)+f(x-1,y)+f(x+1,y)}
在数字图像处理中,数据时以一定的间隔分开的,故无法实行本来意义上的微分运算,所以利用差分实现近似微分值。
为了对微分实行差分近似计算,需要采用表示相邻像素差值的系数组,称为微分算子。具体程序如下:
用一阶微分实现轮廓提取:
#include<math.h>
#include<Params.h>
/** 用一阶微分提取轮廓
image_in:输入图像数组
image_out:输出的图像数组
amp:输出图像的增益
**/
void gradient(unsigned char image_in[ysize][xsize],
unsigned char image_out[ysize][xsize],float amp)
{
static int cx[9]={0,0,0, /*算子的系数x(Roberts)*/
0,1,0, /*采用其他请替换*/
0,0,-1
};
static int cy[9]={0,0,0, /*算子的系数y(Roberts)*/
0,0,1, /*采用其他请替换*/
0,-1,0
};
int d[9];
int i,j,dat;
float xx,yy,zz;
for(i=1;i<ysize-1;i++){
for(j=1;j<xsize-1;j++){
d[0]=image_in[i-1][j-1];
d[1]=image_in[i-1][j];
d[2]=image_in[i-1][j+1];
d[3]=image_in[j-1];
d[4]=image_in[j];
d[5]=image_in[j+1];
d[6]=image_in[i+1][j-1];
d[7]=image_in[i+1][j];
d[8]=image_in[i+1][j+1];
xx=(float)(cx[0]*d[0]+cx[1]*d[1]+cx[2]*d[2]+
cx[3]*d[3]+cx[4]*d[4]+cx[5]*d[5]+
cx[6]*d[6]+cx[7]*d[7]+cx[8]*d[8]
);
yy=(float)(cy[0]*d[0]+cy[1]*d[1]+cy[2]*d[2]+
cy[3]*d[3]+cy[4]*d[4]+cy[5]*d[5]+
cy[6]*d[6]+cy[7]*d[7]+cy[8]*d[8]
);
zz=(float)(amp*sqrt(xx*xx+yy*yy));
dat=(int)zz;
if(dat>255) dat=255;
image_out[j]=(char)dat;
}
}
}
2.用二阶微分提取轮廓
#include<math.h>
#include<Params.h>
/** 用二阶微分提取轮廓
image_in:输入图像数组
image_out:输出的图像数组
amp:输出图像的增益
**/
void lapacian(unsigned char image_in[ysize][xsize],
unsigned char image_out[ysize][xsize],float amp)
{
static int c[9]={-1,-1,-1, /*算子的系数x(lalacian)*/
-1,8,-1, /*采用其他请替换*/
-1,-1,-1
};
int d[9];
int i,j,dat;
float z,zz;
for(i=1;i<ysize-1;i++){
for(j=1;j<xsize-1;j++){
d[0]=image_in[i-1][j-1];
d[1]=image_in[i-1][j];
d[2]=image_in[i-1][j+1];
d[3]=image_in[j-1];
d[4]=image_in[j];
d[5]=image_in[j+1];
d[6]=image_in[i+1][j-1];
d[7]=image_in[i+1][j];
d[8]=image_in[i+1][j+1];
z=(float)(c[0]*d[0]+c[1]*d[1]+c[2]*d[2]+
c[3]*d[3]+c[4]*d[4]+c[5]*d[5]+
c[6]*d[6]+c[7]*d[7]+c[8]*d[8]
);
zzamp*z;
dat=(int)(zz);
if(dat<0) dat=-dat;
if(dat>255)dat=255;
image_out[j]=(char)dat;
}
}
}
文章评论(0条评论)
登录后参与讨论