1.图像的像素值在文件中的存放顺序为从左到右,从下到上,也就是说,在BMP文件中首先存放的是图像的
最后一行像素,最后才存储图像的第一行像素,但对与同一行的像素,则是按照先左边后右边的的顺序存储的
2.文件存储图像的每一行像素值时,如果存储该行像素值所占的字节数为4的倍数,则正常存储否则,需要在后端补0,凑足4的倍数以字节为单位的每行长度始终是4的倍数。行的长度可以计算为:
RowLength = 4 * ((bmch.bcWidth * bmch.bcBitCount + 31) / 32) ; 如果需要,可通过在右边补充行(通常是用零)来完成长度。图素数据的总字节数等于RowLength和bmch.bcHeight的乘积。
3.这些模板的意思可以从不同的角度去解释,可以使用频域的知识,也可以使用统计学的知识,不同的模板有不同用处。模板不是固定不变的,个人认为根据需要可以调整模板中值的分布,这样可以得到的不同的效果。
4.每种滤波都有自己的优势,要根据要求合理使用。可以参考文章:
5.图像处理中每种算法都有很多改进的方法,可以和其他算法混合使用,叫做综合法。或者别的,可以看看这位老兄的博客,讲的很好;
http://hi.baidu.com/liujianz这是均值滤波哪里说的,
这里上传一些数字图像滤波的一些文章:算法的改进方面的文章还有很多但是里面的思想都差不多
边缘图像滤波算法.PDF
一种有效的自适应中值滤波算法.PDF
中值算法改进
中值滤波算法及其并行化研究.PDF
快速向量中值滤波算法.PDF
均值滤波中邻域均值的快速计算.PDF
//**********************************************************************************
//中值滤波函数
//pbmpinfo:图像信息头
//pbmpdata:图像数据
//smoothrect:模板的大小,最小3×3 必须为odd x odd
//**********************************************************************************
//**********************************
//对一组数据进行排序,返回中间值
//length必须是你奇数
// 这个的缺陷:
1.没有考虑模板为偶数的情况
2.排序的算法不是最优化的
//***********************************
unsigned char GetMedian(unsigned char *brray,int length)
{
if (!(length/2) || brray==NULL)
{
return 0;
}
int temp=0;
int i=0,j=0,k=0;
int flag=0;
for (i=1;i<length;i++)
{
flag=0;
for (j = 0;j < length-i ; j++)
{
if (brray[j]>brray[j+1])
{
temp=brray[j];
brray[j]=brray[j+1];
brray[j+1]=temp;
flag=1;
}
}
if (flag==0)
{
break;
}
}
return brray[(length-1)/2];
}
//**********************************************
中值滤波 有的地方叫做排序滤波
BOOL ImgSmooth_Median(BITMAPINFO* pbmpinfo,BYTE* pbmpdata,CSize smoothrect)
{
LONG imagewidth=pbmpinfo->bmiHeader.biWidth;
LONG imageheigth=pbmpinfo->bmiHeader.biHeight;
LONG template_size=smoothrect.cx*smoothrect.cy;
LONG template_width = (smoothrect.cx-1)/2;
LONG template_height = (smoothrect.cy-1)/2;
LONG i=0,j=0,k=0,heigth=0,width=0;
//data is not null
if (pbmpdata == NULL)
{
return FALSE;
}
//image size
if (imageheigth <= smoothrect.cy || imagewidth <= smoothrect.cx)
{
return FALSE;
}
//color must be gray
if (pbmpinfo->bmiHeader.biBitCount != 8)
{
AfxMessageBox("只对灰度图像进行操作!");
return FALSE;
}
//template must be odd x odd
if ( !template_width || !template_height)
{
return FALSE;
}
//开辟一个数组,用来存储数据
unsigned char *array_data=new unsigned char[template_size];
memset(array_data,0,template_size);
//image size
LONG Linebyte =( pbmpinfo->bmiHeader.biBitCount * imagewidth +31)/32*4;
LONG ImageSize=Linebyte * imageheigth;
//分配空间
BYTE *pNewbmpdata=(BYTE*)malloc(ImageSize);
//copy data
if (pNewbmpdata == NULL)
{
delete []array_data;
return FALSE;
}
memcpy(pNewbmpdata,pbmpdata,ImageSize);
BYTE *psrc=NULL;
BYTE *pdest=NULL;
unsigned char tempnum=0;
//计算区域是:begin~image-begin-1 1~image-2
for (heigth = template_height ; heigth < imageheigth - template_height ;heigth++ )
{
for ( width = template_width ; width < imagewidth - template_width ; width++)
{
psrc = pbmpdata+(ImageSize-Linebyte - heigth*Linebyte)+width;
pdest = pNewbmpdata+(ImageSize-Linebyte-heigth*Linebyte)+width;
j=0;
for ( i = - template_height ; i < template_height + 1 ;i++)
{
for (k = - template_width ; k < template_width + 1 ;k++)
{
array_data[j++]=(unsigned char)(*(psrc + i * Linebyte + k));
}
}
tempnum=GetMedian(array_data,template_size);
if (tempnum>255)
{
tempnum=255;
}
if (tempnum<0)
{
tempnum=0;
}
*pdest=(unsigned char)tempnum;
}
}
memcpy(pbmpdata,pNewbmpdata,ImageSize);
free(pNewbmpdata);
delete []array_data;
return TRUE;
}
文章评论(0条评论)
登录后参与讨论