图像特效之径向滤波
1.算法原理
一般模糊算法的基本思想是,目标图像(生成的图像)上的任何一点的颜色值都受源图像对应位置的点以及其附近的点的颜色值共同影响。比如高斯模糊就是将处理点附近的颜色平均值作为该点的颜色。而径向模糊的特点则是某个中心点颜色向外扩散,这说明从中心点指向外侧的一条直线上,远离中心点的点是不会影响比较靠近中心点的点。另外,由于颜色是向四处发散,则不同放射线上的颜色也不会相互影响。
那么,我们可以将径向模糊算法归结为,目标图像上的某点颜色值为源图像对应点向中心点方向上一定距离的像素平均值。求这些采样点的加权平均作为目标点。当然,有一定的采样距离,离目标点越近采样的越多些。如下图所示。
2.代码实现
int Radial_Filtering(IMAGE_TYPE *bmp_img)
{
DWORD width,height,dst_index,index,DisX,DisY;
WORD biBitCount;
T_U8 *bmp_data,Gray,R,G,B,*GrayImage,*Result_img;
T_U32 line_byte,TmpR,TmpG,TmpB ;
T_U16 i,j,k,num = 25;
int newX,newY;
POINTTU32 Center = {0};
double Dis,angle,TmpDis;
BITMAPFILEHEADER bf;
BITMAPINFOHEADER bi;
FILE *Radial_Filter_BMP_fp = fopen("Radial_Filter_BMP.bmp","wb");
if(NULL == Radial_Filter_BMP_fp)
{
printf("Can't open Radial_Filter_BMP.bmp\n");
return -1;
}
memset(&bf, 0, sizeof(bf));
memset(&bi, 0, sizeof(bi));
memcpy(&bf,bmp_img,14);
memcpy(&bi,&bmp_img[14],40);
height = bi.biHeight;
width = bi.biWidth;
biBitCount = bi.biBitCount;//每一个像素由24 bits表示,即RGB分量每一个分量用8 bits表示
line_byte =(width*3+3) & ~0x3;
fwrite(&bf,sizeof(BITMAPFILEHEADER),1,Radial_Filter_BMP_fp);
fwrite(&bi,sizeof(BITMAPINFOHEADER),1,Radial_Filter_BMP_fp);
Result_img = (T_U8*)malloc(height*line_byte*sizeof(T_U8));
if(Result_img == NULL)
{
printf("Can't malloc for image.\n");
return -1;
}
memset(Result_img,0,height*line_byte*sizeof(T_U8));
bmp_data = bmp_img + BMPHEADSIZE;
Center.x = width/2;
Center.y = height/2;
for(i = 0;i < height;i++)
{
DisY = labs((i-Center.y));
for(j = 0;j <width;j++)
{
dst_index = i*line_byte+j*3;
DisX = labs((j-Center.x));
Dis = sqrt(pow((double)DisX,2)+pow((double)DisY,2));
angle = atan2((double)(i-Center.y),(double)(j-Center.x));
TmpR = 0;
TmpG = 0;
TmpB = 0;
for(k = 0;k < num;k++)
{
#if 1
//旋转径向模糊
angle += 0.01;
newX = (int)(Dis*cos(angle) + Center.x);
newY = (int)(Dis*sin(angle) + Center.y);
#endif
#if 0
//径向模糊
TmpDis =(Dis-k)>0?(Dis-k):0;
newX = (int)(TmpDis*cos(angle) + Center.x);
newY = (int)(TmpDis*sin(angle) + Center.y);
#endif
if(newX<0)newX=0;
if(newX>width-1)newX=width-1;
if(newY<0)newY=0;
if(newY>height-1)newY=height-1;
index = newY*line_byte+3*newX;
TmpR += bmp_data[index+2];
TmpG += bmp_data[index+1];
TmpB += bmp_data[index];
}
Result_img[dst_index+2] =CLIP255(TmpR/num);
Result_img[dst_index+1] = CLIP255(TmpG/num);
Result_img[dst_index+0] = CLIP255(TmpB/num);
}
}
fwrite(Result_img, line_byte*height*sizeof(T_U8), 1, Radial_Filter_BMP_fp);
fclose(Radial_Filter_BMP_fp);
free(Result_img);
return 0;
}
3.图像效果
从左到右:原始图像、径向模糊、旋转径向模糊
参考资料:
http://blog.csdn.net/bluecol/article/details/38961617
http://bbs.9ria.com/thread-111831-1-1.html
http://blog.csdn.net/yangtrees/article/details/9103935