📄 dibimage.cpp
字号:
// 循环控制变量
int k ;
// 图象的横纵坐标,用来对当前象素的4邻域进行遍历
while (Start<=End)
{
// 当前种子点的坐标
Current.x = GrowX[Start];
Current.y = GrowY[Start];
// 对当前点的4邻域进行遍历
for (k=0; k<4; k++)
{
// 4邻域象素的坐标
xx = Current.x+Dx[k];
yy = Current.y+Dy[k];
// 判断象素(xx,yy) 是否在图像内部
// 判断象素(xx,yy) 是否已经处理过
// *lpDst==255 表示还没有处理
// 指向源图像(xx,yy)象素的指针
lpSrc = (unsigned char *)lpDIBBits + lWidth * (lHeight-yy) + xx;
lpSrc1 = (unsigned char *)lpDIBBits + lWidth * (lHeight-Current.y) + Current.x;
// 指向目标图像第j行,第i个象素的指针
lpDst = (unsigned char *)lpImage + lWidth * (lHeight-yy) + xx;
// 生长条件:判断象素(xx,yy)和当前象素(nCurrX,nCurrY) 象素值差的绝对值
if ((xx < lWidth) && (xx>=0) && (yy<lHeight) && (yy>=0) && (*lpDst==255)
&& abs(*lpSrc-*lpSrc1)<Dib_yuzhi )
{
// 堆栈的尾部指针后移一位
End++;
// 象素(xx,yy) 压入栈
GrowX[End] = xx;
GrowY[End] = yy;
// 目标图像为黑点,同时也表明该象素处理过
*lpDst=0 ;
}
}
Start++;
}
// 复制区域生长后的图像
memcpy(lpDIBBits, lpImage, lWidth * lHeight);
// 释放内存
delete[] lpImage;
delete[] GrowX;
delete[] GrowY;
// 返回
// return TRUE;
}
/*************************************************************************
* 函数名称:
* TongJi() --统计灰度分布密度
* 参数:
* LPSTR lpDIB - 指向DIB对象的指针
* float *tongji - 指向灰度分布密度的指针
* 返回值:
* 无
* 说明:
* 该函数用来统计图象中的灰度分布密度
*************************************************************************/
void CDibImage::TongJi(LPSTR lpDIB,float *tongji)
{ // 循环变量
int i;
int j;
// 灰度计数
int huidu[256];
int wide,height; //原图长、宽
// 变量初始化
memset(huidu,0,sizeof(huidu));
wide=DIBWidth(lpDIB);
height=DIBHeight(lpDIB);
LPBYTE temp1=new BYTE[wide*height+1024]; //新图像缓冲区
memcpy( temp1,FindDIBBits(lpDIB),wide*height ); //拷贝原图像到缓存图像
// 对各像素进行灰度统计
for (i = 0; i < height; i ++)
{
for (j = 0; j <wide; j ++)
{
unsigned char temp = temp1[wide* i + j] ;
// 灰度统计计数
huidu[temp]++;
}
}
// 计算灰度分布密度
for(i=0;i<256;i++)
tongji[i] = huidu[i] / (height * wide *1.0f);
}
/*************************************************************************
* 函数名称:
* MuBiaoErZhiHua() --目标选择法阈值分割
* 参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* LPSTR lpDIB - 指向DIB对象的指针
* LONG lWidth - 源图像宽度(象素数)
* LONG lHeight - 源图像高度(象素数)
* int xx - 种子点的横坐标
* int yy - 种子点的纵坐标
* 返回值:
* 无
* 说明:
* 将图象中的像素点与种子点的像素值差值比较,小于标准差的归0,大于标准差的归255
*************************************************************************/
void CDibImage::MuBiaoErZhiHua(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int xx, int yy)
{
unsigned char* lpSrc; // 指向DIB第i行,第j个象素的指针
int ZhongZi; // 记录种子点的像素值
LONG i; // 循环变量
LONG j;
LONG lLineBytes; // 图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);// 计算图像每行的字节数
ZhongZi=*((unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - yy) + xx);
BYTE* p_temp=new BYTE[lWidth*lHeight];// 申请并分配中间缓存
memcpy(p_temp,lpDIBBits,lWidth*lHeight);// 复制图象数据到中间缓存
for(i = 0; i < lHeight; i++) // 每行
{
for(j = 0; j < lWidth; j++) // 每列
{
// 指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
if (abs((*lpSrc)-ZhongZi)<30) // 判断是否小于标准差10
{
*(p_temp + lLineBytes * (lHeight - 1 - i) + j)=0;
}
else
{
*(p_temp + lLineBytes * (lHeight - 1 - i) + j)=255;
}
}
}
memcpy(lpDIBBits,p_temp,lWidth*lHeight); // 复制中间缓存到图象数据
delete p_temp;
}
/*****************************************************
*
* 函数名称:
* Template:
*
* 参数:
* HDIB hDIB -图像的句柄
* int tem_w -模板的宽度
* int tem_h -模板的高度
*
* 功能:
* 对图像进行中值
*
* 说明:
* 为处理方便起见,模板的宽度和高度都应为奇数
*******************************************************/
HDIB CDibImage::MidFilter(HDIB hDIB,int tem_w,int tem_h)
{
//统计中间值
double mid;
BYTE *temp=(BYTE*)malloc(tem_w*tem_h*sizeof(BYTE));
//指向图像起始位置的指针
BYTE *lpDIB=(BYTE*)GlobalLock((HGLOBAL) hDIB);
//指向象素起始位置的指针
BYTE *pScrBuff =(BYTE*)FindDIBBits((char*)lpDIB);
//获取图像的颜色信息
int numColors=(int)DIBNumColors((char *)lpDIB);
//如果图像不是256色返回
if (numColors!=256)
{
//解除锁定
GlobalUnlock((HGLOBAL) hDIB);
//返回
return(hDIB);
}
//将指向图像象素起始位置的指针,赋值给指针变量
BYTE* oldbuf = pScrBuff;
//循环变量
int i,j,m,n;
int w, h, dw;
//获取图像的宽度
w = (int) DIBWidth((char *)lpDIB);
//获取图像的高度
h = (int) DIBHeight((char *)lpDIB);
//计算图像每行的字节数
dw = (w+3)/4*4;
//建立一个和原图像大小相同的25色灰度位图
HDIB newhDIB=NewDIB(w,h,8);
//指向新的位图的指针
BYTE *newlpDIB=(BYTE*)GlobalLock((HGLOBAL) newhDIB);
//指向新的位图的象素起始位置的指针
BYTE *destBuf = (BYTE*)FindDIBBits((char *)newlpDIB);
//将指向新图像象素起始位置的指针,赋值给指针变量
BYTE *newbuf=destBuf;
//对图像进行扫描
//行
for(i=0;i<h;i++)
{
//列
for(j=0;j<w;j++)
{
//为统计变量赋初始值
//对于图像的4个边框的象素保持原灰度不变
if( j<((tem_w-1)/2) || j>(w-(tem_w+1)/2) || i<((tem_h-1)/2) || i>(h-(tem_h+1)/2) )
*(newbuf+i*dw+j)=*(oldbuf+i*dw+j);
//对于其他的象素进行模板操作
else
{
//将点(i,j)点作为模板的中心
for(m=i-((tem_h-1)/2);m<=i+((tem_h-1)/2);m++)
{
for(n=j-((tem_w-1)/2);n<=j+((tem_w-1)/2);n++)
//将以点(i,j)为中心,与模板大小相同的范围内的象素传递到模板矩阵中
temp[(m-i+((tem_h-1)/2))*tem_w+n-j+((tem_w-1)/2)]=*(oldbuf+m*dw+n);
}
//利用气泡法计算中值
for(m=0;m<tem_w*tem_h-1;m++)
{
for(n=0;n<tem_w*tem_h-m-1;n++)
{
if(temp[n]>temp[n+1])
mid=temp[n];
temp[n]=temp[n+1];
temp[n+1]=mid;
}
}
//将计算的结果放到新的位图的相应位置
*(newbuf+i*dw+j)=temp[(tem_w*tem_h-1)/2];
}
}
}
//解除锁定
::GlobalUnlock((HGLOBAL)hDIB);
//返回新的位图的句柄
return(newhDIB);
}
HDIB CDibImage::NewDIB(long width, long height, unsigned short biBitCount)
{
long dwindth = (width*biBitCount/8+3)/4*4; // align 4 bytes
WORD color_num;
switch(biBitCount)
{
case 1:
color_num=2;
break;
case 4:
color_num=16;
break;
case 8:
color_num=256;
break;
default:
color_num=0;
break;
}
long dwBitsSize = dwindth *height + 40 + color_num*4;// 40 LPBIMHEAD
LPSTR pDIB;
HDIB hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
if (hDIB == 0)
{
return NULL;
}
pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
LPBITMAPINFO lpmf = (LPBITMAPINFO)pDIB;
lpmf->bmiHeader.biSize = 40;//40
lpmf->bmiHeader.biWidth = width; //i_info.width;
lpmf->bmiHeader.biHeight = height;
lpmf->bmiHeader.biPlanes = 1;
lpmf->bmiHeader.biBitCount = biBitCount;// 24
lpmf->bmiHeader.biCompression = 0;
lpmf->bmiHeader.biSizeImage = dwindth *height;
lpmf->bmiHeader.biXPelsPerMeter = 2925;
lpmf->bmiHeader.biYPelsPerMeter = 2925;
lpmf->bmiHeader.biClrUsed = 0;
lpmf->bmiHeader.biClrImportant= 0;
if(color_num!=0)
{
for(int i=0;i<color_num;i++)
{
lpmf->bmiColors[i].rgbRed =(BYTE)i;
lpmf->bmiColors[i].rgbGreen =(BYTE)i;
lpmf->bmiColors[i].rgbBlue =(BYTE)i;
}
}
::GlobalUnlock((HGLOBAL) hDIB);
return hDIB;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -