数学形态学是建立在集合理论基础上的一门科学,其强大的理论武器可以把它运用到很多领域中,下面是数学形态学在图像处理上的运用,这里只是数学形态学上的最基本操作和最重要的操作,腐蚀和膨胀。
腐蚀:
void Binary_Erosion::fuzhi()
{
int i;
msk[0][0]=0;msk[0][1]=0;msk[0][2]=0;msk[0][3]=255;msk[0][4]=0;msk[0][5]=0;msk[0][6]=0;
msk[1][0]=0;msk[1][1]=0;msk[1][2]=255; msk[1][3]=255;msk[1][4]=255;msk[1][5]=0;msk[1][6]=0;
msk[2][0]=0;msk[2][6]=0;
for(i=1;i<6;i++)
msk[2][i]=255;
for(i=0;i<7;i++)
msk[3][i]=255;
msk[4][0]=0;msk[4][6]=0;
for(i=1;i<6;i++)
msk[4][i]=255;
msk[5][0]=0;msk[5][1]=0;msk[5][2]=255;
msk[5][3]=255;msk[5][4]=255;msk[5][5]=0;msk[5][6]=0;
msk[6][0]=0;msk[6][1]=0;msk[6][2]=0;msk[6][3]=255;msk[6][4]=0;msk[6][5]=0;msk[6][6]=0;
}
void Binary_Erosion::binary_erosion(QImage *img)
{
//i,j,s,t分别为循环变量,mx,my为结构化元素的大小
int i,j,s,t,mx=3,my=3;
//获得图像的宽度和高度
unsigned char flg;
int w=img->width();
int h=img->height();
//对结构化元素进行赋值
fuzhi();
//动态定义一个二维数组
double **new_img=new double*[h];
for(i=0;i<h;i++)
{
*(new_img+i)=new double[w];
}
//对二维数组赋初值
for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
new_img[i][j]=0;
}
//下面算法同膨胀大同小异,比较简单,这里就不在赘述了
for(i=0;i<h;i++)
for(j=0;j<w;j++)
{
flg=0;
for(s=-(my);s<=my;s++)
{
for(t=(-mx);t<=mx;t++)
{
if(((i+s)>=0)&&((i+s)<h)&&((j+t)>=0)&&((j+t)<w))
{
if((msk[s+my][t+mx]==255)&&(qGray(img->pixel(j+t,i+s))!=255))
{
flg=1;
break;
}
}
else
{
flg=1;
break;
}
}
if(flg)
break;
}
if(flg==0)
new_img[i][j]=255;
}
//修改像素值
for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
img->setPixel(j,i,qRgb(new_img[i][j],new_img[i][j],new_img[i][j]));
}
}
膨胀:
void Binary_Erosion::fuzhi()
{
int i;
msk[0][0]=0;msk[0][1]=0;msk[0][2]=0;msk[0][3]=255;msk[0][4]=0;msk[0][5]=0;msk[0][6]=0;
msk[1][0]=0;msk[1][1]=0;msk[1][2]=255; msk[1][3]=255;msk[1][4]=255;msk[1][5]=0;msk[1][6]=0;
msk[2][0]=0;msk[2][6]=0;
for(i=1;i<6;i++)
msk[2][i]=255;
for(i=0;i<7;i++)
msk[3][i]=255;
msk[4][0]=0;msk[4][6]=0;
for(i=1;i<6;i++)
msk[4][i]=255;
msk[5][0]=0;msk[5][1]=0;msk[5][2]=255;
msk[5][3]=255;msk[5][4]=255;msk[5][5]=0;msk[5][6]=0;
msk[6][0]=0;msk[6][1]=0;msk[6][2]=0;msk[6][3]=255;msk[6][4]=0;msk[6][5]=0;msk[6][6]=0;
}
void Binary_Erosion::binary_erosion(QImage *img)
{
//i,j,s,t分别为循环变量,mx,my为结构化元素的大小
int i,j,s,t,mx=3,my=3;
//获得图像的宽度和高度
unsigned char flg;
int w=img->width();
int h=img->height();
//对结构化元素进行赋值
fuzhi();
//动态定义一个二维数组
double **new_img=new double*[h];
for(i=0;i<h;i++)
{
*(new_img+i)=new double[w];
}
//对二维数组赋初值
for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
new_img[i][j]=0;
}
//下面算法同膨胀大同小异,比较简单,这里就不在赘述了
for(i=0;i<h;i++)
for(j=0;j<w;j++)
{
flg=0;
for(s=-(my);s<=my;s++)
{
for(t=(-mx);t<=mx;t++)
{
if(((i+s)>=0)&&((i+s)<h)&&((j+t)>=0)&&((j+t)<w))
{
if((msk[s+my][t+mx]==255)&&(qGray(img->pixel(j+t,i+s))!=255))
{
flg=1;
break;
}
}
else
{
flg=1;
break;
}
}
if(flg)
break;
}
if(flg==0)
new_img[i][j]=255;
}
//修改像素值
for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
img->setPixel(j,i,qRgb(new_img[i][j],new_img[i][j],new_img[i][j]));
}
}