📄 operation.cpp
字号:
//Operation.cpp
#include "stdafx.h"
#include "Operation.h"
#include "DIBAPI.h"
#include <math.h>
#include <direct.h>
/*************************************************************************
*
* 函数名称:
* Template()
*
* 参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* LONG lWidth - 源图像宽度(象素数)
* LONG lHeight - 源图像高度(象素数)
* int iTempH - 模板的高度
* int iTempW - 模板的宽度
* int iTempMX - 模板的中心元素X坐标 ( < iTempW - 1)
* int iTempMY - 模板的中心元素Y坐标 ( < iTempH - 1)
* double * fpArray - 指向模板数组的指针
* double fCoef - 模板系数
*
* 返回值:
* BOOL - 成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数用指定的模板(任意大小)来对图像进行操作,参数iTempH指定模板
* 的高度,参数iTempW指定模板的宽度,参数iTempMX和iTempMY指定模板的中心
* 元素坐标,参数fpArray指定模板元素,fCoef指定系数。
*
************************************************************************/
BOOL WINAPI Template(LPSTR lpDIBBits, LONG lWidth, LONG lHeight,
int iTempH, int iTempW,
int iTempMX, int iTempMY,
double * fpArray, double fCoef)
{
// 指向复制图像的指针
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;
// 指向源图像的指针
unsigned char* lpSrc;
// 指向要复制区域的指针
unsigned char* lpDst;
// 循环变量
LONG i;
LONG j;
LONG k;
LONG l;
// 计算结果
double fResult;
// 图像每行的字节数
LONG lLineBytes;
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
// 暂时分配内存,以保存新图像
hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);
// 判断是否内存分配失败
if (hNewDIBBits == NULL)
{
// 分配内存失败
return FALSE;
}
// 锁定内存
lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
// 初始化图像为原始图像
memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight);
// 行(除去边缘几行)
for(i = iTempMY; i < lHeight - iTempH + iTempMY + 1; i++)
{
// 列(除去边缘几列)
for(j = iTempMX; j < lWidth - iTempW + iTempMX + 1; j++)
{
// 指向新DIB第i行,第j个象素的指针
lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j;
fResult = 0;
// 计算
for (k = 0; k < iTempH; k++)
{
for (l = 0; l < iTempW; l++)
{
// 指向DIB第i - iTempMY + k行,第j - iTempMX + l个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i + iTempMY - k)
+ j - iTempMX + l;
// 保存象素值
fResult += (* lpSrc) * fpArray[k * iTempW + l];
}
}
// 乘上系数
fResult *= fCoef;
// 取绝对值
fResult = (double ) fabs(fResult);
// 判断是否超过255
if(fResult > 255)
{
// 直接赋值为255
* lpDst = 255;
}
else
{
// 赋值
* lpDst = (unsigned char) (fResult + 0.5);
}
}
}
// 复制变换后的图像
memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
// 释放内存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
// 返回
return TRUE;
}
/*************************************************************************
*
* 函数名称:
* GaussDIB()
*
* 参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* LONG lWidth - 源图像宽度(象素数,必须是4的倍数)
* LONG lHeight - 源图像高度(象素数)
* 返回值:
* BOOL - 边缘检测成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数用高斯拉普拉斯边缘检测算子对图像进行边缘检测运算。
*
* 要求目标图像为灰度图像。
************************************************************************/
BOOL WINAPI GaussDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
// 指向缓存图像的指针
LPSTR lpDst1;
LPSTR lpDst2;
// 指向缓存DIB图像的指针
LPSTR lpNewDIBBits1;
HLOCAL hNewDIBBits1;
LPSTR lpNewDIBBits2;
HLOCAL hNewDIBBits2;
// 模板高度
int iTempH;
// 模板宽度
int iTempW;
// 模板系数
double fTempC;
// 模板中心元素X坐标
int iTempMX;
// 模板中心元素Y坐标
int iTempMY;
//模板数组
double aTemplate[25];
// 暂时分配内存,以保存新图像
hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight);
if (hNewDIBBits1 == NULL)
{
// 分配内存失败
return FALSE;
}
// 锁定内存
lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1);
// 暂时分配内存,以保存新图像
hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight);
if (hNewDIBBits2 == NULL)
{
// 分配内存失败
return FALSE;
}
// 锁定内存
lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2);
// 拷贝源图像到缓存图像中
lpDst1 = (char *)lpNewDIBBits1;
memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight);
lpDst2 = (char *)lpNewDIBBits2;
memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);
// 设置Gauss模板参数
iTempW = 5;
iTempH = 5;
fTempC = 1.0;
iTempMX = 3;
iTempMY = 3;
aTemplate[0] = -2.0;
aTemplate[1] = -4.0;
aTemplate[2] = -4.0;
aTemplate[3] = -4.0;
aTemplate[4] = -2.0;
aTemplate[5] = -4.0;
aTemplate[6] = 0.0;
aTemplate[7] = 8.0;
aTemplate[8] = 0.0;
aTemplate[9] = -4.0;
aTemplate[10] = -4.0;
aTemplate[11] = 8.0;
aTemplate[12] = 24.0;
aTemplate[13] = 8.0;
aTemplate[14] = -4.0;
aTemplate[15] = -4.0;
aTemplate[16] = 0.0;
aTemplate[17] = 8.0;
aTemplate[18] = 0.0;
aTemplate[19] = -4.0;
aTemplate[20] = -2.0;
aTemplate[21] = -4.0;
aTemplate[22] = -4.0;
aTemplate[23] = -4.0;
aTemplate[24] = -2.0;
// 调用Template()函数
if (!Template(lpNewDIBBits1, lWidth, lHeight,
iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))
{
return FALSE;
}
// 复制经过模板运算后的图像到源图像
memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight);
// 释放内存
LocalUnlock(hNewDIBBits1);
LocalFree(hNewDIBBits1);
LocalUnlock(hNewDIBBits2);
LocalFree(hNewDIBBits2);
// 返回
return TRUE;
}
/*************************************************************************
*
* 函数名称:
* CalThreshold()
*
* 参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* LONG lWidth - 源图像宽度(象素数,必须是4的倍数)
* LONG lHeight - 源图像高度(象素数)
* 返回值:
* double - 返回阈值。
*
* 说明:
* 该函数用将图像所有元素均值作为阈值。
*
* 要求目标图像为灰度图像。
************************************************************************/
double WINAPI CalThreshold(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
// 指向原图像的指针
unsigned char* lpSrc;
// 循环变量
LONG i;
LONG j;
// 计算结果
double fResult=0.0;
// 图像每行的字节数
LONG lLineBytes;
//计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
//每行
for(i=0;i<lHeight;i++)
{
//每列
for(j=0;j<lWidth;j++)
{
//指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
//叠加
fResult = fResult + *lpSrc;
}
}
//计算均值
fResult = fResult/(lHeight*lWidth);
return fResult;
}
/*************************************************************************
*
* 函数名称:
* EventDetect()
*
* 参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* LONG lWidth - 源图像宽度(象素数,必须是4的倍数)
* LONG lHeight - 源图像高度(象素数)
* double fThre - 阈值
* 返回值:
* BOOL -均值检测成功返回true 。
*
* 说明:
* 该函数用将图像用均值作为阈值进行二值化。
*
* 要求目标图像为灰度图像。
************************************************************************/
BOOL WINAPI EvenDetect(LPSTR lpDIBBits, LONG lWidth, LONG lHeight,double fThre)
{
// 指向缓存图像的指针
LPSTR lpDst1;
LPSTR lpDst2;
// 指向缓存DIB图像的指针
LPSTR lpNewDIBBits1;
HLOCAL hNewDIBBits1;
LPSTR lpNewDIBBits2;
HLOCAL hNewDIBBits2;
// 模板高度
int iTempH;
// 模板宽度
int iTempW;
// 模板系数
double fTempC;
// 模板中心元素X坐标
int iTempMX;
// 模板中心元素Y坐标
int iTempMY;
//模板数组
double aTemplate[25];
// 暂时分配内存,以保存新图像
hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight);
if (hNewDIBBits1 == NULL)
{
// 分配内存失败
return FALSE;
}
// 锁定内存
lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1);
// 暂时分配内存,以保存新图像
hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight);
if (hNewDIBBits2 == NULL)
{
// 分配内存失败
return FALSE;
}
// 锁定内存
lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2);
// 拷贝源图像到缓存图像中
lpDst1 = (char *)lpNewDIBBits1;
memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight);
lpDst2 = (char *)lpNewDIBBits2;
memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);
// 设置Gauss模板参数
iTempW = 5;
iTempH = 5;
fTempC = 0.04;
iTempMX = 3;
iTempMY = 3;
aTemplate[0] = 1;
aTemplate[1] = 1;
aTemplate[2] = 1;
aTemplate[3] = 1;
aTemplate[4] = 1;
aTemplate[5] = 1;
aTemplate[6] = 1;
aTemplate[7] = 1;
aTemplate[8] = 1;
aTemplate[9] = 1;
aTemplate[10] = 1;
aTemplate[11] = 1;
aTemplate[12] = 1;
aTemplate[13] = 1;
aTemplate[14] = 1;
aTemplate[15] = 1;
aTemplate[16] = 1;
aTemplate[17] = 1;
aTemplate[18] = 1;
aTemplate[19] = 1;
aTemplate[20] = 1;
aTemplate[21] = 1;
aTemplate[22] = 1;
aTemplate[23] = 1;
aTemplate[24] = 1;
// 调用Template()函数
if (!Template(lpNewDIBBits1, lWidth, lHeight,
iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))
{
return FALSE;
}
// 复制经过模板运算后的图像到源图像
memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight);
// 指向源图像的指针
unsigned char* lpSrc;
// 循环变量
LONG i;
LONG j;
// 图像每行的字节数
LONG lLineBytes;
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
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 ((*lpSrc) < fThre-50)
{
// 直接赋值为0
*lpSrc = 0;
}
else
{
// 直接赋值为255
*lpSrc = 255;
}
}
}
// 释放内存
LocalUnlock(hNewDIBBits1);
LocalFree(hNewDIBBits1);
LocalUnlock(hNewDIBBits2);
LocalFree(hNewDIBBits2);
// 返回
return TRUE;
}
/*************************************************************************
*
* 函数名称:
* LightingCompensate()
*
* 参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* LONG lWidth - 源图像宽度(象素数,必须是4的倍数)
* LONG lHeight - 源图像高度(象素数)
* 返回值:
* BOOL - 光度补偿成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数对图像进行光度补偿。
*
* 要求目标图像为灰度图像。
************************************************************************/
BOOL WINAPI LightingCompensate(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
// 指向源图像的指针
unsigned char* lpSrc;
// 循环变量
LONG i;
LONG j;
// 图像每行的字节数
LONG lLineBytes;
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);
// 每行
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 ((*lpSrc) > 100)
{
// 直接赋值为0
*lpSrc = 255;
}
}
}
// 返回
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -