📄 spacefilter.cpp
字号:
// ************************************************************************
// 文件名:SpaceFilter.cpp
//
// 图像空域滤波处理函数库:
//
// MakeEmboss() - 浮雕化处理
// PixelFilter() - 对图象进行小区域模版滤波
// StencilFilter() - 对图象进行模版滤波
// MedianFilter() - 对图象进行中值滤波(非线形平滑滤波)
// OverRun() - 对图象进行超限模版滤波处理
//
// ************************************************************************
#include "stdafx.h"
#include "dip_system.h"
#include "SpaceFilter.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define MAX(a,b) ((a)>(b))?(a):(b)
#define MIN(a,b) ((a)<(b))?(a):(b)
#define BOUND(c,i,j) (MAX((i),MIN((c),(j))))
/////////////////////////////////////////////////////////////////////////////
// CSpaceFilter
CSpaceFilter::CSpaceFilter()
{
}
CSpaceFilter::~CSpaceFilter()
{
}
BEGIN_MESSAGE_MAP(CSpaceFilter, CWnd)
//{{AFX_MSG_MAP(CSpaceFilter)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSpaceFilter message handlers
/*************************************************************************
*
* 函数名称:
* PixelFilter()
*
* 参数:
* LPBYTE lpDst - 目标图象数据
* LPBYTE lpSrc - 源图象数据
* LPKERNEL lpKernel - 指向KERNEL结构对象的指针
* DWORD dwWidthBytes - 一行图象所占字节数
* BOOL bEmboss - 是否需要增强处理
*
* 返回值:
* 无返回值
*
* 说明:
* 该函数将对图象进行小区域模版滤波
*
************************************************************************/
void CSpaceFilter::PixelFilter(LPBYTE lpDst, LPBYTE lpSrc, LPKERNEL lpKernel, DWORD dwWidthBytes, BOOL bEmboss)
{
// 循环变量
LONG i;
LONG j;
// 临时变量
LONG temp;
LONG R;
LONG G;
LONG B;
LPBYTE lpTemp1;
LPBYTE lpTemp2;
// 初始化
R = G = B = 0;
// lpTemp1 = lpSrc + dwWidthBytes - 3
lpTemp1 = lpSrc + dwWidthBytes - lpKernel->Dimention;
// 对小区域进行模版空域滤波
for(i = 0; i < lpKernel->Dimention; i++)
{
lpTemp2 = lpTemp1;
for(j = 0; j < lpKernel->Dimention; j++)
{
temp = lpKernel->Element[i][j];
B += (*lpTemp2++) * temp;
G += (*lpTemp2++) * temp;
R += (*lpTemp2++) * temp;
}
lpTemp1 -= dwWidthBytes;
}
// 取模版除数
temp = lpKernel->Divisor;
if(temp != 1)
{
R /= temp;
G /= temp;
B /= temp;
}
// 如浮雕处理则需将背景色置为RGB(128,128,128)
if(bEmboss)
{
R += 128;
G += 128;
B += 128;
}
// 防止超界
R = BOUND(R,0,255);
G = BOUND(G,0,255);
B = BOUND(B,0,255);
// 将处理后结果保存到DIB
*lpDst++ = (BYTE)B;
*lpDst++ = (BYTE)G;
*lpDst = (BYTE)R;
}
/*************************************************************************
*
* 函数名称:
* MakeEmboss()
*
* 参数:
* HDIB hDIB - 待处理的DIB
* int nEmbossMode - 采取的浮雕化模式
*
* 返回值:
* HDIB - 新的DIB
*
* 说明:
* 该函数将彩色位图进行浮雕化处理
*
************************************************************************/
HDIB CSpaceFilter::MakeEmboss(HDIB hDIB, int nEmbossMode)
{
// 循环变量
LONG i;
LONG j;
LONG k;
// 获取指向KERNEL结构对象的指针
LPKERNEL lpKernel = &Emboss[nEmbossMode];
// 新DIB句柄
HDIB hNewDIB;
// 指向DIB的指针
LPBYTE lpDIB;
LPBYTE lpNewDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
LPBYTE lpNewDIBBits;
// 指向BITMAPINFO结构的指针(Win3.0)
LPBITMAPINFOHEADER lpbmi;
// 指向BITMAPCOREINFO结构的指针
LPBITMAPCOREHEADER lpbmc;
// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB图像象素起始位置
lpDIBBits = (LPBYTE)m_clsDIB.FindDIBBits(lpDIB);
// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用户
MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return NULL;
}
// 更改光标形状
BeginWaitCursor();
// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 计算图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 24);
// 分配内存,以保存新DIB
hNewDIB = (HDIB) ::GlobalAlloc(GHND, lLineBytes * lHeight
+ *(LPDWORD)lpDIB + m_clsDIB.PaletteSize(lpDIB));
// 判断是否内存分配失败
if (hNewDIB == NULL)
{
// 分配内存失败
return NULL;
}
// 锁定内存
lpNewDIB = (LPBYTE)::GlobalLock((HGLOBAL) hNewDIB);
// 复制DIB信息头和调色板
memcpy(lpNewDIB, lpDIB, *(LPDWORD)lpDIB + m_clsDIB.PaletteSize(lpDIB));
// 找到新DIB象素起始位置
lpNewDIBBits = (LPBYTE)m_clsDIB.FindDIBBits(lpNewDIB);
// 获取指针
lpbmi = (LPBITMAPINFOHEADER)lpNewDIB;
lpbmc = (LPBITMAPCOREHEADER)lpNewDIB;
// 更新DIB中图像的高度和宽度
if (IS_WIN30_DIB(lpNewDIB))
{
// 对于Windows 3.0 DIB
lpbmi->biWidth = lWidth;
lpbmi->biHeight = lHeight;
}
else
{
// 对于其它格式的DIB
lpbmc->bcWidth = (unsigned short) lWidth;
lpbmc->bcHeight = (unsigned short) lHeight;
}
// 临时变量
LPBYTE lpSrcTemp,lpDstTemp;
LPBYTE lpSrcPixel,lpDstPixel;
// 图象第一行地址
lpSrcTemp = lpDIBBits + (lHeight - 1) * lLineBytes;
lpDstTemp = lpNewDIBBits + (lHeight - 1) * lLineBytes;
// 复制图像的第一行;
memcpy(lpDstTemp, lpSrcTemp, lLineBytes);
// 修正指针
lpSrcTemp -= lLineBytes;
lpDstTemp -= lLineBytes;
// 对整幅图象实施小区域空域滤波处理
for(i = 0; i< lHeight - 2; i++)
{
lpSrcPixel = lpSrcTemp;
lpDstPixel = lpDstTemp;
// 复制每行的第一个像素;
for(k = 0; k < 3; k++)
{
*lpDstPixel = *lpSrcPixel;
lpDstPixel++;
lpSrcPixel++;
}
// 调用小区域滤波函数对各行数据进行处理
for(j = 0; j < lWidth - 2; j++)
{
PixelFilter(lpDstPixel, lpSrcPixel, lpKernel, lLineBytes, TRUE);
lpSrcPixel += 3;
lpDstPixel += 3;
}
// 复制每行的最后一个像素;
for(k = 0; k < 3; k++)
{
*lpDstPixel = *lpSrcPixel;
lpDstPixel++;
lpSrcPixel++;
}
// 修正指针
lpSrcTemp -= lLineBytes;
lpDstTemp -= lLineBytes;
}
//复制图像的最后一行;
memcpy(lpDstTemp, lpSrcTemp, lLineBytes);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 恢复光标
EndWaitCursor();
return hNewDIB;
}
/*************************************************************************
*
* 函数名称:
* StencilFilter()
*
* 参数:
* HDIB hDIB - 待处理的DIB
* LPKERNEL lpKernel - 获取指向KERNEL结构对象的指针
*
* 返回值:
* 无返回值
*
* 说明:
* 该函数将彩色位图进行模版滤波处理
*
************************************************************************/
void CSpaceFilter::StencilFilter(HDIB hDIB, LPKERNEL lpKernel)
{
// 循环变量
LONG i;
LONG j;
LONG k;
LONG l;
// 临时变量
LONG R, G, B;
// 指向DIB的指针
LPBYTE lpDIB;
// 指向DIB象素指针
LPBYTE lpDIBBits;
// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);
// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用户
MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);
// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);
// 返回
return;
}
// 更改光标形状
BeginWaitCursor();
// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);
// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);
// 计算图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 24);
// 申请并分配中间缓存
HLOCAL hLocal = LocalAlloc(GHND, lLineBytes * lHeight);
if (hLocal == NULL)
return;
LPBYTE m_temp = (LPBYTE)LocalLock(hLocal);
// 复制图象数据到中间缓存
for (i = 0; i < lHeight; i ++)
{
for (j = 0; j < lLineBytes; j ++)
{
*(m_temp + lLineBytes * i + j) = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
j++;
*(m_temp + lLineBytes * i + j) = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
j++;
*(m_temp + lLineBytes * i + j) = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
}
}
// 模版滤波
for (i = 0; i < lWidth; i++) //被处理像素在i列
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -