边缘检测函数名称:EdgeDetection()
参数:
LPSTR lpDIBBits - 指向源DIB图像指针
LONG lWidth - 源图像宽度(象素数,必须是4的倍数)
LONG lHeight - 源图像高度(象素数)
返回值: BOOL - 边缘检测成功返回TRUE,否则返回FALSE。
说明:该函数用Sobel边缘检测算子对图像进行边缘检测运算。
BOOL EdgeDetection(LPSTR lpDIBBits, LONG lmageWidth, LONG lmageHeight,int mode)
{
int nTempWidth; //模板的宽度
int nTempHeight; // 模板的高度
int nTempCenX; //模板中心的X坐标(相对于模板)
int nTempCenY; //模板中心的Y坐标(相对于模板)
double* Tempdata; //模板数组的指针
double TempCoef; //模板系数
//循环变量
int i;
int j;
// 指向缓存图像的指针
unsigned char* lpDst1;
unsigned char* lpDst2;
// 指向存贮图像的指针
LPBYTE lpImage1;
LPBYTE lpImage2;
// 暂时分配内存,以保存新图像
lpImage1 = (LPBYTE) new char[lmageWidth*lmageHeight];
lpImage2 = (LPBYTE) new char[lmageWidth*lmageHeight];
// 判断是否内存分配失败
if (lpImage1 == NULL)
{
// 分配内存失败
return FALSE;
}
// 判断是否内存分配失败
if (lpImage2 == NULL)
{
// 分配内存失败
return FALSE;
}
// 初始化图像为原始图像
memcpy(lpImage1, lpDIBBits, lmageWidth*lmageHeight);
memcpy(lpImage2, lpDIBBits, lmageWidth*lmageHeight);
lpDst1 = (unsigned char*)lpImage1;
lpDst2 = (unsigned char*)lpImage2;
//Sobel算子水平检测模板参数
nTempWidth=3;
nTempHeight=3;
nTempCenX=1;
nTempCenY=1;
TempCoef=1;
Tempdata=new double[9];//Sobel算子模板为3X3
//水平向模板参数
Tempdata[0]=-1;
Tempdata[1]=-2;
Tempdata[2]=-1;
Tempdata[3]=0;
Tempdata[4]=0;
Tempdata[5]=0;
Tempdata[6]=1;
Tempdata[7]=2;
Tempdata[8]=1;
if (!Template((LPSTR)lpImage1, lmageWidth, lmageHeight,nTempWidth, nTempHeight,
nTempCenX, nTempCenY,Tempdata, TempCoef))//调用模板操作函数Template()对图像进行Sobel模板纵向检测
{
return FALSE;
}
//垂直方向模板参数
Tempdata[0]=-1;
Tempdata[1]=0;
Tempdata[2]=1;
Tempdata[3]=-2;
Tempdata[4]=0;
Tempdata[5]=2;
Tempdata[6]=-1;
Tempdata[7]=0;
Tempdata[8]=1;
if (!Template((LPSTR)lpImage2, lmageWidth, lmageHeight,nTempWidth, nTempHeight,
nTempCenX, nTempCenY,Tempdata, TempCoef))//调用模板操作函数Template()对图像进行Sobel模板横向检测
{
return FALSE;
}
delete[] Tempdata;
//求两幅缓存图像的最大值
for(j = 0; j <lmageHeight; j++)
{
for(i = 0;i <lmageWidth; i++)
{
// 指向缓存图像1倒数第j行,第i个象素的指针
lpDst1 = (unsigned char*)lpImage1 + lmageWidth * j + i;
// 指向缓存图像2倒数第j行,第i个象素的指针
lpDst2 = (unsigned char*)lpImage2 + lmageWidth * j + i;
if(*lpDst2 > *lpDst1)
{
*lpDst1 = *lpDst2;
}
}
}
//复制经过模板运算后的图像到源图像
memcpy(lpDIBBits, lpImage1,lmageWidth*lmageHeight);
return TRUE;
}
模板操作函数名称:Template()
输入参数:
LPSTR lpDIBBits - 指向源图像的像素指针
LONG lmageWidth - 源图像的宽度
LONG lmageHeight - 源图像的高度
int nTempWidth - 模板的宽度
int nTempHeight - 模板的高度
int nTempCenX - 模板中心的X坐标(相对于模板)
int nTempCenY - 模板中心的Y坐标(相对于模板)
double* Tempdata - 模板数组的指针
double* TempCoef - 模板的系数
返回值: BOOL - 成功则返回TRUE,否则返回FALSE
说明:该函数用指定的模板对lpDIBBits指向的图象进行模板操作。模板的定义了宽度,高度,中心坐标
和系数,模板的数据存放在Tempdata中。对图象进行模板操作后,仍然存放在lpDIBBits指向的对象
中。需要注意的是,该函数只能处理8位的图象,否则,指向的数据将出错。
BOOL Template(LPSTR lpDIBBits, LONG lmageWidth, LONG lmageHeight,
int nTempWidth, int nTempHeight,
int nTempCenX, int nTempCenY,
double* Tempdata, double TempCoef)
{
LPBYTE lpImage; // 临时存放图像数据的指针
int i; // 循环变量
int j; // 循环变量
int k; // 循环变量
int l; // 循环变量
unsigned char* lpSrc; // 指向源图像的指针
unsigned char* lpDst; // 指向要复制区域的指针
double dbResult; // 计算结果
lpImage = (LPBYTE) new char[lmageWidth*lmageHeight]; // 分配内存
if (lpImage == NULL) // 判断是否内存分配失败
{
return FALSE; // 分配内存失败
}
// 将原始图像的数据拷贝到临时存放内存中
memcpy(lpImage, lpDIBBits, lmageWidth*lmageHeight);
// 进行模板计算,行(除去边缘几行)
for(i = nTempCenY ; i <lmageHeight - nTempHeight + nTempCenY + 1; i++)
{
// 列(除去边缘几列)
for(j = nTempCenX; j < lmageWidth - nTempWidth + nTempCenX + 1; j++)
{
// 指向新DIB第i行,第j个象素的指针
lpDst = (unsigned char*)lpImage + lmageWidth * (lmageHeight - 1 - i) + j;
dbResult = 0; // 置0
for (k = 0; k < nTempHeight; k++)
{
for (l = 0; l < nTempWidth; l++)
{
// 指向DIB第i - iFilterMY + k行,第j - iFilterMX + l个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lmageWidth * (lmageHeight - 1 - i + nTempCenY - k) + j - nTempCenX + l;
dbResult += (* lpSrc) * Tempdata[k * nTempWidth + l]; // 保存象素值
}
}
dbResult *= TempCoef; // 乘上系数
dbResult = (double ) fabs(dbResult); // 取绝对值
if(dbResult > 255) // 判断是否超过255
{
* lpDst = 255; // 直接赋值为255
}
else
{
* lpDst = (unsigned char) (dbResult + 0.5); // 赋值
}
}
}
memcpy(lpDIBBits, lpImage, lmageWidth*lmageHeight); //复制变换后的图像
delete[] lpImage; // 释放内存
return TRUE; // 返回
}