mathmorphology.cpp
来自「visual c++数字图像与图形处理中的光盘内容」· C++ 代码 · 共 1,035 行 · 第 1/2 页
CPP
1,035 行
//第四步
//先进行膨胀, 然后进行腐蚀
Dilate(pcxDataSrc, w, h, pcxDataDst);
Erode(pcxDataDst, w, h, pcxDataSrc);
//第五步
//指向内存目标数据
pcxDataFore = pcxDataSrc;
dwBaseIndex = y * dwWidthBytes + 4 * x;
for(i = 0;i < h;i++)
{
//指向一行的开始数据
BYTE* pbyDst = lpbyBits32 + dwBaseIndex;
for(j = 0;j < w;j++)
{
short cxBlue = *pcxDataFore++;
short cxGreen = *pcxDataFore++;
short cxRed = *pcxDataFore++;
*pbyDst++ = (BYTE)BOUND(cxBlue, 0, 255);
*pbyDst++ = (BYTE)BOUND(cxGreen, 0, 255);
*pbyDst++ = (BYTE)BOUND(cxRed, 0, 255);
pbyDst++;
}
dwBaseIndex += dwWidthBytes;
}
delete[] pcxDataSrc;
delete[] pcxDataDst;
return TRUE;
}
//提取边界
BOOL CMathMorphology::PickEdge(LPBYTE lpbyBits32, int x, int y, int nWidth, int nHeight, int nScanWidth, int nScanHeight)
{
//第一步, 进行参数合法性检测
ASSERT(lpbyBits32);
ASSERT(m_pME);
if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
m_dwOperation = IMAGE_MATH_MORPHOLOGY_PICK_DETECT;
//有效区域的宽度和高度
int w = min(nWidth, nScanWidth - x);
int h = min(nHeight, nScanHeight - y);
//第二步, 分配内存空间, 结果只可能在(-255, +255)之间,
//存储蓝色、绿色、红色
int nSize = w * h;
//存储源
short* pcxDataSrc = new short[(nSize * 3)];
if (pcxDataSrc == NULL) return FALSE;
//存储目标
short* pcxDataDst = new short[(nSize * 3)];
if (pcxDataDst == NULL) return FALSE;
//第三步, 获取输入图像的数据
//行字节数
DWORD dwWidthBytes = (DWORD)nScanWidth * 4;
//开始数据基索引
DWORD dwBaseIndex = y * dwWidthBytes + 4 * x;
//指向内存源数据
short* pcxDataFore = pcxDataSrc;
int i, j;
for(i = 0;i < h;i++)
{
//指向一行的开始数据
BYTE* pbySrc = lpbyBits32 + dwBaseIndex;
for(j = 0;j < w;j++)
{
//blue
*pcxDataFore++ = *pbySrc++;
//green
*pcxDataFore++ = *pbySrc++;
//red
*pcxDataFore++ = *pbySrc++;
pbySrc++;
}
dwBaseIndex += dwWidthBytes;
}
//第四步
//先进行腐蚀
Erode(pcxDataSrc, w, h, pcxDataDst);
//第五步
//指向内存目标数据
pcxDataFore = pcxDataSrc;
short* pcxDataAfter = pcxDataDst;
dwBaseIndex = y * dwWidthBytes + 4 * x;
for(i = 0;i < h;i++)
{
//指向一行的开始数据: 目标
BYTE* pbyDst = lpbyBits32 + dwBaseIndex;
for(j = 0;j < w;j++)
{
short cxBlue = ((*pcxDataFore++) - (*pcxDataAfter++));
short cxGreen = ((*pcxDataFore++) - (*pcxDataAfter++));
short cxRed = ((*pcxDataFore++) - (*pcxDataAfter++));
//执行归入至[0,255]的运算
*pbyDst++ = (BYTE)BOUND(cxBlue, 0, 255);
*pbyDst++ = (BYTE)BOUND(cxGreen, 0, 255);
*pbyDst++ = (BYTE)BOUND(cxRed, 0, 255);
pbyDst++;
}
dwBaseIndex += dwWidthBytes;
}
delete[] pcxDataSrc;
delete[] pcxDataDst;
return TRUE;
}
//开合成
BOOL CMathMorphology::OpenCompose(LPBYTE lpbyBits32, int x, int y, int nWidth, int nHeight, int nScanWidth, int nScanHeight)
{
//第一步, 进行参数合法性检测
ASSERT(lpbyBits32);
ASSERT(m_pME);
if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
m_dwOperation = IMAGE_MATH_MORPHOLOGY_OPEN_COMPOSE;
//有效区域的宽度和高度
int w = min(nWidth, nScanWidth - x);
int h = min(nHeight, nScanHeight - y);
//第二步, 分配内存空间, 结果只可能在(-255, +255)之间,
//存储蓝色、绿色、红色
int nSize = w * h;
//存储源
short* pcxDataSrc = new short[(nSize * 3)];
if (pcxDataSrc == NULL) return FALSE;
//存储目标
short* pcxDataDst = new short[(nSize * 3)];
if (pcxDataDst == NULL) return FALSE;
//第三步, 获取输入图像的数据
//行字节数
DWORD dwWidthBytes = (DWORD)nScanWidth * 4;
//开始数据基索引
DWORD dwBaseIndex = y * dwWidthBytes + 4 * x;
//指向内存源数据
short* pcxDataFore = pcxDataSrc;
int i, j;
for(i = 0;i < h;i++)
{
//指向一行的开始数据
BYTE* pbySrc = lpbyBits32 + dwBaseIndex;
for(j = 0;j < w;j++)
{
//blue
*pcxDataFore++ = *pbySrc++;
//green
*pcxDataFore++ = *pbySrc++;
//red
*pcxDataFore++ = *pbySrc++;
pbySrc++;
}
dwBaseIndex += dwWidthBytes;
}
//保存中间结果
short* pcxDataTemp = new short[(nSize * 3)];
if (pcxDataTemp == NULL) return FALSE;
//第四步
//先进行膨胀, 然后进行腐蚀,
Erode(pcxDataSrc, w, h, pcxDataTemp);
Dilate(pcxDataTemp, w, h, pcxDataDst);
//第五步
//指向内存目标数据
pcxDataFore = pcxDataSrc;
short* pcxDataAfter = pcxDataDst;
dwBaseIndex = y * dwWidthBytes + 4 * x;
for(i = 0;i < h;i++)
{
//指向一行的开始数据: 目标
BYTE* pbyDst = lpbyBits32 + dwBaseIndex;
for(j = 0;j < w;j++)
{
short cxBlue = ((*pcxDataFore++) + (*pcxDataAfter++));
short cxGreen = ((*pcxDataFore++) + (*pcxDataAfter++));
short cxRed = ((*pcxDataFore++) + (*pcxDataAfter++));
*pbyDst++ = (BYTE)BOUND(cxBlue, 0, 255);
*pbyDst++ = (BYTE)BOUND(cxGreen, 0, 255);
*pbyDst++ = (BYTE)BOUND(cxRed, 0, 255);
pbyDst++;
}
dwBaseIndex += dwWidthBytes;
}
delete[] pcxDataSrc;
delete[] pcxDataDst;
delete[] pcxDataTemp;
return TRUE;
}
//去噪声
BOOL CMathMorphology::Denoise(LPBYTE lpbyBits32, int x, int y, int nWidth, int nHeight, int nScanWidth, int nScanHeight)
{
//第一步, 进行参数合法性检测
ASSERT(lpbyBits32);
ASSERT(m_pME);
if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
m_dwOperation = IMAGE_MATH_MORPHOLOGY_DENOISE;
//有效区域的宽度和高度
int w = min(nWidth, nScanWidth - x);
int h = min(nHeight, nScanHeight - y);
//第二步, 分配内存空间, 结果只可能在(-255, +255)之间,
//存储蓝色、绿色、红色
int nSize = w * h;
//存储源
short* pcxDataSrc = new short[(nSize * 3)];
if (pcxDataSrc == NULL) return FALSE;
//存储目标
short* pcxDataDst = new short[(nSize * 3)];
if (pcxDataDst == NULL) return FALSE;
//第三步, 获取输入图像的数据
//行字节数
DWORD dwWidthBytes = (DWORD)nScanWidth * 4;
//开始数据基索引
DWORD dwBaseIndex = y * dwWidthBytes + 4 * x;
//指向内存源数据
short* pcxDataFore = pcxDataSrc;
int i, j;
for(i = 0;i < h;i++)
{
//指向一行的开始数据
BYTE* pbySrc = lpbyBits32 + dwBaseIndex;
for(j = 0;j < w;j++)
{
//blue
*pcxDataFore++ = *pbySrc++;
//green
*pcxDataFore++ = *pbySrc++;
//red
*pcxDataFore++ = *pbySrc++;
pbySrc++;
}
dwBaseIndex += dwWidthBytes;
}
//第四步
//进行降噪声处理
//先进行腐蚀, 然后进行膨胀, 膨胀, 腐蚀
Erode(pcxDataSrc, w, h, pcxDataDst);
Dilate(pcxDataDst, w, h, pcxDataSrc);
Dilate(pcxDataSrc, w, h, pcxDataDst);
Erode(pcxDataDst, w, h, pcxDataSrc);
//第五步
//指向内存目标数据
pcxDataFore = pcxDataSrc;
dwBaseIndex = y * dwWidthBytes + 4 * x;
for(i = 0;i < h;i++)
{
//指向一行的开始数据
BYTE* pbyDst = lpbyBits32 + dwBaseIndex;
for(j = 0;j < w;j++)
{
short cxBlue = *pcxDataFore++;
short cxGreen = *pcxDataFore++;
short cxRed = *pcxDataFore++;
*pbyDst++ = (BYTE)BOUND(cxBlue, 0, 255);
*pbyDst++ = (BYTE)BOUND(cxGreen, 0, 255);
*pbyDst++ = (BYTE)BOUND(cxRed, 0, 255);
pbyDst++;
}
dwBaseIndex += dwWidthBytes;
}
delete[] pcxDataSrc;
delete[] pcxDataDst;
return TRUE;
}
//形态学梯度
BOOL CMathMorphology::Gradientize(LPBYTE lpbyBits32, int x, int y, int nWidth, int nHeight, int nScanWidth, int nScanHeight)
{
//第一步, 进行参数合法性检测
ASSERT(lpbyBits32);
ASSERT(m_pME);
if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
m_dwOperation = IMAGE_MATH_MORPHOLOGY_GRADIENTIZE;
//有效区域的宽度和高度
int w = min(nWidth, nScanWidth - x);
int h = min(nHeight, nScanHeight - y);
//第二步, 分配内存空间, 结果只可能在(-255, +255)之间,
//存储蓝色、绿色、红色
int nSize = w * h;
//存储源
short* pcxDataSrc = new short[(nSize * 3)];
if (pcxDataSrc == NULL) return FALSE;
//存储目标
short* pcxDataDst = new short[(nSize * 3)];
if (pcxDataDst == NULL) return FALSE;
//第三步, 获取输入图像的数据
//行字节数
DWORD dwWidthBytes = (DWORD)nScanWidth * 4;
//开始数据基索引
DWORD dwBaseIndex = y * dwWidthBytes + 4 * x;
//指向内存源数据
short* pcxDataFore = pcxDataSrc;
int i, j;
for(i = 0;i < h;i++)
{
//指向一行的开始数据
BYTE* pbySrc = lpbyBits32 + dwBaseIndex;
for(j = 0;j < w;j++)
{
//blue
*pcxDataFore++ = *pbySrc++;
//green
*pcxDataFore++ = *pbySrc++;
//red
*pcxDataFore++ = *pbySrc++;
pbySrc++;
}
dwBaseIndex += dwWidthBytes;
}
//保存中间结果
short* pcxDataTemp = new short[(nSize * 3)];
if (pcxDataTemp == NULL) return FALSE;
//第四步
//进行形态学梯度
Dilate(pcxDataSrc, w, h, pcxDataTemp);
Erode(pcxDataSrc, w, h, pcxDataDst);
//第五步
//指向内存目标数据
pcxDataFore = pcxDataTemp;
short* pcxDataAfter = pcxDataDst;
dwBaseIndex = y * dwWidthBytes + 4 * x;
for(i = 0;i < h;i++)
{
//指向一行的开始数据
BYTE* pbyDst = lpbyBits32 + dwBaseIndex;
for(j = 0;j < w;j++)
{
short cxBlue = ((*pcxDataFore++) - (*pcxDataAfter++));
short cxGreen = ((*pcxDataFore++) - (*pcxDataAfter++));
short cxRed = ((*pcxDataFore++) - (*pcxDataAfter++));
*pbyDst++ = (BYTE)BOUND(cxBlue, 0, 255);
*pbyDst++ = (BYTE)BOUND(cxGreen, 0, 255);
*pbyDst++ = (BYTE)BOUND(cxRed, 0, 255);
pbyDst++;
}
dwBaseIndex += dwWidthBytes;
}
delete[] pcxDataSrc;
delete[] pcxDataDst;
delete[] pcxDataTemp;
return TRUE;
}
//高帽变换
BOOL CMathMorphology::TopHat(LPBYTE lpbyBits32, int x, int y, int nWidth, int nHeight, int nScanWidth, int nScanHeight)
{
//第一步, 进行参数合法性检测
ASSERT(lpbyBits32);
ASSERT(m_pME);
if((x > (nScanWidth - 1)) || (y > (nScanHeight - 1))) return FALSE;
m_dwOperation = IMAGE_MATH_MORPHOLOGY_TOP_HAT;
//有效区域的宽度和高度
int w = min(nWidth, nScanWidth - x);
int h = min(nHeight, nScanHeight - y);
//第二步, 分配内存空间, 结果只可能在(-255, +255)之间,
//存储蓝色、绿色、红色
int nSize = w * h;
//存储源
short* pcxDataSrc = new short[(nSize * 3)];
if (pcxDataSrc == NULL) return FALSE;
//存储目标
short* pcxDataDst = new short[(nSize * 3)];
if (pcxDataDst == NULL) return FALSE;
//第三步, 获取输入图像的数据
//行字节数
DWORD dwWidthBytes = (DWORD)nScanWidth * 4;
//开始数据基索引
DWORD dwBaseIndex = y * dwWidthBytes + 4 * x;
//指向内存源数据
short* pcxDataFore = pcxDataSrc;
int i, j;
for(i = 0;i < h;i++)
{
//指向一行的开始数据
BYTE* pbySrc = lpbyBits32 + dwBaseIndex;
for(j = 0;j < w;j++)
{
//blue
*pcxDataFore++ = *pbySrc++;
//green
*pcxDataFore++ = *pbySrc++;
//red
*pcxDataFore++ = *pbySrc++;
pbySrc++;
}
dwBaseIndex += dwWidthBytes;
}
//保存中间结果
short* pcxDataTemp = new short[ (nSize * 3) ];
if (pcxDataTemp == NULL) return FALSE;
//第四步
//先进行膨胀, 然后进行腐蚀,
Erode(pcxDataSrc, w, h, pcxDataTemp);
Dilate(pcxDataTemp, w, h, pcxDataDst);
//第五步
//指向内存目标数据
pcxDataFore = pcxDataSrc;
short* pcxDataAfter = pcxDataDst;
dwBaseIndex = y * dwWidthBytes + 4 * x;
for(i = 0;i < h;i++)
{
//指向一行的开始数据: 目标
BYTE* pbyDst = lpbyBits32 + dwBaseIndex;
for(j = 0;j < w;j++)
{
short cxBlue = ((*pcxDataFore++) - (*pcxDataAfter++));
short cxGreen = ((*pcxDataFore++) - (*pcxDataAfter++));
short cxRed = ((*pcxDataFore++) - (*pcxDataAfter++));
*pbyDst++ = (BYTE)BOUND(cxBlue, 0, 255);
*pbyDst++ = (BYTE)BOUND(cxGreen, 0, 255);
*pbyDst++ = (BYTE)BOUND(cxRed, 0, 255);
pbyDst++;
}
dwBaseIndex += dwWidthBytes;
}
delete[] pcxDataSrc;
delete[] pcxDataDst;
delete[] pcxDataTemp;
return TRUE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?