【数字图像处理】图像增强-空域-空间滤波模板类 & 算子总结

【数字图像处理】图像增强-空域-空间滤波模板类 & 算子总结(MFC & 滤镜)

模板类

空间滤波就是在原图像上做卷积运算,这里给出一个改进过的模板类。

BOOL WINAPI Template(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int iTempH, int iTempW, int iTempMX, int iTempMY, FLOAT* fpArray, FLOAT fCoef, LONG lLineBytes, FLOAT thre);
//最后在传统模板类加上 float 阈值,使模板类可以完成反色

函数库.cpp

/*************************************************************************
 *
 * 函数名称:
 *   Template()
 *
 * 参数:
 *   LPSTR lpDIBBits    - 指向源DIB图像指针
 *   LONG  lWidth       - 源图像宽度(象素数)
 *   LONG  lHeight      - 源图像高度(象素数)
 *   int   iTempH		- 模板的高度
 *   int   iTempW		- 模板的宽度
 *   int   iTempMX		- 模板的中心元素X坐标 ( < iTempW - 1)
 *   int   iTempMY		- 模板的中心元素Y坐标 ( < iTempH - 1)
 *	 FLOAT * fpArray	- 指向模板数组的指针
 *	 FLOAT 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, FLOAT* fpArray, FLOAT fCoef,LONG lLineBytes, FLOAT thre)
{
	// 指向复制图像的指针
	LPSTR lpNewDIBBits;
	HLOCAL hNewDIBBits;

	// 指向源图像的指针
	unsigned char* lpSrc;

	// 指向要复制区域的指针
	unsigned char* lpDst;

	// 循环变量
	LONG i;
	LONG j;
	LONG k;
	LONG l;

	// 计算结果
	FLOAT fResult;

	// 暂时分配内存,以保存新图像
	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 + -0.1行,第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 += thre;

			// 取绝对值
			fResult = (FLOAT)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;
}

xxxxview.cpp

void CImgView::Onfilter()//滤镜操作
{
	CImgDoc* pDoc = GetDocument();
	long lSrcLineBytes;		//图象每行的字节数
	long lSrcWidth;      //图象的宽度和高度
	long lSrcHeight;
	int lpSrcBitCount;       //图像的位深
	LPSTR	lpSrcDib;		//指向源图象的指针	
	LPSTR	lpSrcStartBits;	//指向源像素的指针
	lpSrcDib = (LPSTR) ::GlobalLock((HGLOBAL)pDoc->GetHObject());// 锁定DIB
	if (!lpSrcDib) return;
	if (pDoc->m_dib.GetColorNum(lpSrcDib) != 256)// 判断是否是8-bpp位图
	{
		AfxMessageBox(L"对不起,不是256色位图!");// 警告				
		::GlobalUnlock((HGLOBAL)pDoc->GetHObject());// 解除锁定		
		return;									//返回
	}										//判断是否是8-bpp位图,不是则返回	
	lpSrcStartBits = pDoc->m_dib.GetBits(lpSrcDib);			// 找到DIB图象像素起始位置	
	lSrcWidth = pDoc->m_dib.GetWidth(lpSrcDib);					// 获取图象的宽度		
	lSrcHeight = pDoc->m_dib.GetHeight(lpSrcDib);					// 获取图象的高度	
	lpSrcBitCount = pDoc->m_dib.GetBitCount(lpSrcDib);                    //获取图像位深
	lSrcLineBytes = pDoc->m_dib.GetReqByteWidth(lSrcWidth * 8);		// 计算图象每行的字节数
	/
	int iTempH;      // 模板高度
	int iTempW;      // 模板宽度
	FLOAT fTempC;    // 模板系数
	int iTempMX;     // 模板中心元素X坐标
	int iTempMY;     // 模板中心元素Y坐标
	FLOAT aValue[9]; // 模板元素数组
	float thre;

	CDlgFilter Dlgfil;

	Dlgfil.lSrcHeight = lSrcHeight;
	Dlgfil.lSrcWidth = lSrcWidth;
	Dlgfil.lpSrcStartBits = lpSrcStartBits;
	Dlgfil.Doc = pDoc;
	Dlgfil.lSrcLineBytes = lSrcLineBytes;
	Dlgfil.lpSrcDib = lpSrcDib;

	if (Dlgfil.DoModal() != IDOK)
	{
		return;
	}

	aValue[0] = Dlgfil.Num[0];
	aValue[1] = Dlgfil.Num[1];
	aValue[2] = Dlgfil.Num[2];
	aValue[3] = Dlgfil.Num[3];
	aValue[4] = Dlgfil.Num[4];
	aValue[5] = Dlgfil.Num[5];
	aValue[6] = Dlgfil.Num[6];
	aValue[7] = Dlgfil.Num[7];
	aValue[8] = Dlgfil.Num[8];

	// 设定平移量(3*3)
	iTempH = 3;
	iTempW = 3;//这里用的都是3x3的模板,直接赋值为3了
	iTempMX = Dlgfil.m_iTempMX;
	iTempMY = Dlgfil.m_iTempMY;
	fTempC = Dlgfil.m_fTempC;
	thre = Dlgfil.Thre;
	delete Dlgfil;
	// 更改光标形状

	BeginWaitCursor();

	// 调用Template()函数
	if (Template(lpSrcStartBits, lSrcWidth, lSrcHeight, iTempH, iTempW, iTempMX, iTempMY, aValue, fTempC, lSrcLineBytes,thre))
	{
		pDoc->SetModifiedFlag(TRUE);// 设置脏标记

		pDoc->UpdateAllViews(NULL);// 更新视图
	}
	else
	{
		// 提示用户
		AfxMessageBox(L"分配内存失败!");
	}

	// 解除锁定
	::GlobalUnlock((HGLOBAL)pDoc->GetHObject());

	// 恢复光标
	EndWaitCursor();
}

算子总结

m_iTempH :模板的高度
m_iTempW :模板的宽度
m_iTempMX :模板中心坐标x
m_iTempMY :模板中心坐标y
m_fTempC :模板系数
Thre :为了把反色统一进模板类单独加的,反色是255,其他均为0

高斯模糊

m_iTempH = 3;
m_iTempW = 3;
m_iTempMX = 1;
m_iTempMY = 1;
m_fTempC = (FLOAT)(1.0 / 16.0);
Thre =0;

Num[0] = 1.0;
Num[1] = 2.0;
Num[2] = 1.0;
Num[3] = 2.0;
Num[4] = 4.0;
Num[5] = 2.0;
Num[6] = 1.0;
Num[7] = 2.0;
Num[8] = 1.0;

均值模糊

m_iTempH = 3;
m_iTempW = 3;
m_iTempMX = 1;
m_iTempMY = 1;
m_fTempC = (FLOAT)(1.0 / 9.0);
Thre = 0;

Num[0] = 1.0;
Num[1] = 1.0;
Num[2] = 1.0;
Num[3] = 1.0;
Num[4] = 1.0;
Num[5] = 1.0;
Num[6] = 1.0;
Num[7] = 1.0;
Num[8] = 1.0;

反色

m_iTempH = 3;
m_iTempW = 3;
m_iTempMX = 1;
m_iTempMY = 1;
m_fTempC = -1;
Thre = 255;

Num[0] = 0;
Num[1] = 0;
Num[2] = 0;
Num[3] = 0;
Num[4] = 1.0;
Num[5] = 0;
Num[6] = 0;
Num[7] = 0;
Num[8] = 0;

拉普拉斯锐化

m_iTempH = 3;
m_iTempW = 3;
m_iTempMX = 1;
m_iTempMY = 1;
m_fTempC = 1;
Thre = 0;

Num[0] = 1.0;
Num[1] = 1.0;
Num[2] = 1.0;
Num[3] = 1.0;
Num[4] = -8.0;
Num[5] = 1.0;
Num[6] = 1.0;
Num[7] = 1.0;
Num[8] = 1.0;

浮雕

m_iTempH = 3;
m_iTempW = 3;
m_iTempMX = 1;
m_iTempMY = 1;
m_fTempC = 1.0;
Thre = 0;

Num[0] = -2;
Num[1] = -1;
Num[2] = 0;
Num[3] = -1;
Num[4] = 1;
Num[5] = 1;
Num[6] = 0;
Num[7] = 1;
Num[8] = 2;

Sobel

m_iTempH = 3;
m_iTempW = 3;
m_iTempMX = 1;
m_iTempMY = 1;
m_fTempC = 1.0;

Gy:

Num[0] = -1;
Num[1] = 0;
Num[2] = 1;
Num[3] = -2;
Num[4] = 0;
Num[5] = 2;
Num[6] = -1;
Num[7] = 0;
Num[8] = 1;

Gx:

Num[0] = 1;
Num[1] = 2;
Num[2] = 1;
Num[3] = 0;
Num[4] = 0;
Num[5] = 0;
Num[6] = -1;
Num[7] = -2;
Num[8] = -1;

Prewitt

m_iTempH = 3;
m_iTempW = 3;
m_iTempMX = 1;
m_iTempMY = 1;
m_fTempC = 1.0;
Thre = 0;

Gx:

Num[0] = 1;
Num[1] = 1;
Num[2] = 1;
Num[3] = 0;
Num[4] = 0;
Num[5] = 0;
Num[6] = -1;
Num[7] = -1;
Num[8] = -1;

Gy:

Num[0] = -1;
Num[1] = 0;
Num[2] = 1;
Num[3] = -1;
Num[4] = 0;
Num[5] = 1;
Num[6] = -1;
Num[7] = 0;
Num[8] = 1;

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值