⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 morph.cpp

📁 其中包括图像压缩的基本编码方法如Huffman编码算术编码JPEG 2000H.261压缩编码标准小波变换编码运动估计算法视频图象采集的VC实现等.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				{
					*lpDst = 0;
					*(lpDst + 1) = 0;
					*(lpDst + 2) = 0;
					continue;
				}

				// 判断条件二是否成立:
				nCount = 0;
				
				if (S[1][2] == 0 && S[1][1] == 1) 
					nCount++;
				if (S[1][1] == 0 && S[2][1] == 1)
					nCount++;
				if (S[2][1] == 0 && S[3][1] == 1)
					nCount++;
				if (S[3][1] == 0 && S[3][2] == 1)
					nCount++;
				if (S[3][2] == 0 && S[3][3] == 1)
					nCount++;
				if (S[3][3] == 0 && S[2][3] == 1)
					nCount++;
				if (S[2][3] == 0 && S[1][3] == 1)
					nCount++;
				if (S[1][3] == 0 && S[1][2] == 1)
					nCount++;

				if (nCount != 1)
				{
					*lpDst = 0;
					*(lpDst + 1) = 0;
					*(lpDst + 2) = 0;
					continue;
				}

				// 判断条件三是否成立;
				if (S[1][2] * S[2][1] * S[2][3] != 0)
				{
					nCount = 0;
					if (S[0][2] == 0 && S[0][1] == 1)
						nCount++;
					if (S[0][1] == 0 && S[1][1] == 1)
						nCount++;
					if (S[1][1] == 0 && S[2][1] == 1)
						nCount++;
					if (S[2][1] == 0 && S[2][2] == 1)
						nCount++;
					if (S[2][2] == 0 && S[2][3] == 1)
						nCount++;
					if (S[2][3] == 0 && S[1][3] == 1)
						nCount++;
					if (S[1][3] == 0 && S[0][3] == 1)
						nCount++;
					if (S[0][3] == 0 && S[0][2] == 1)
						nCount++;

					if (nCount == 1)
					{
						*lpDst = 0;
						*(lpDst + 1) = 0;
						*(lpDst + 2) = 0;
						continue;
					}
				}

				// 判断条件四是否成立:
				if (S[1][2] * S[2][1] * S[3][2] != 0)
				{
					nCount = 0;
					if (S[1][1] == 0 && S[1][0] == 1)
						nCount++;
					if (S[1][0] == 0 && S[2][0] == 1)
						nCount++;
					if (S[2][0] == 0 && S[3][0] == 1)
						nCount++;
					if (S[3][0] == 0 && S[3][1] == 1)
						nCount++;
					if (S[3][1] == 0 && S[3][2] == 1)
						nCount++;
					if (S[3][2] == 0 && S[2][2] == 1)
						nCount++;
					if (S[2][2] == 0 && S[1][2] == 1)
						nCount++;
					if (S[1][2] == 0 && S[1][1] == 1)
						nCount++;
					if (nCount == 1)
					{
						*lpDst = 0;
						*(lpDst + 1) = 0;
						*(lpDst + 2) = 0;
						continue;
					}
				}

				// 如果条件均满足则删除该点
				*lpDst = 255;
				*(lpDst + 1) = 255;
				*(lpDst + 2) = 255;
				bJump = TRUE;
			}
		}

		// 复制腐蚀后的图像
		memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
	}
	
	// 复制腐蚀后的图像
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);

	// 解除锁定
	::GlobalUnlock((HGLOBAL) hDIB);

	// 释放内存
	LocalUnlock(hNewDIBBits);
	LocalFree(hNewDIBBits);

	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   Thick() 
 * 
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图象进行粗化处理
 *
 ************************************************************************/

void CMorph::Thick(HDIB hDIB)
{
	// 循环变量
	LONG i;
	LONG j;

	// 指向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);
	
	// 对各像素进行灰度转换
	for (i = 0; i < lHeight; i ++)
	{
		for (j = 0; j < lLineBytes; j ++)
		{
			// 对像素各颜色分量进行二值化求补处理
			unsigned char R = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			if (R > 127)
				*((unsigned char *)lpDIBBits + lLineBytes * i + j) = 0;
			else
				*((unsigned char *)lpDIBBits + lLineBytes * i + j) = 255;
			j++;
			
			unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			if (G > 127)
				*((unsigned char *)lpDIBBits + lLineBytes * i + j) = 0;
			else
				*((unsigned char *)lpDIBBits + lLineBytes * i + j) = 255;
			j++;

			unsigned char B = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			if (B >127)
				*((unsigned char *)lpDIBBits + lLineBytes * i + j) = 0;
			else
				*((unsigned char *)lpDIBBits + lLineBytes * i + j) = 0;
		}
	}

	// 解除锁定
	::GlobalUnlock((HGLOBAL) hDIB);

	// 在求补后再对图象进行细化
	Thin(hDIB);

	// 恢复光标 
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   MAT() 
 * 
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图象进行中轴变换
 *
 ************************************************************************/

void CMorph::MAT(HDIB hDIB)
{
	// 循环变量 
	LONG i;
	LONG j;
	LONG m;
	LONG n;

	// 5×5相邻区域像素值
	unsigned char S[5][5];

	// 计数器
	unsigned char nCount;

	// 循环跳出标志 
	BOOL bJump;

	// 指向DIB的指针
	LPBYTE lpDIB;
	
	// 指向DIB象素指针
	LPBYTE lpDIBBits;
	
	// 指向源图像的指针
	LPBYTE	lpSrc;
	
	// 指向缓存图像的指针
	LPBYTE	lpDst;

	// 指向缓存DIB图像的指针
	LPBYTE	lpNewDIBBits;
	HLOCAL	hNewDIBBits;

	// 锁定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);

	// 暂时分配内存,以保存新图像
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);

	if (hNewDIBBits == NULL)
	{
		// 分配内存失败
		return;
	}
	
	// 锁定内存	
	lpNewDIBBits = (LPBYTE)LocalLock(hNewDIBBits);

	// 初始化新分配的内存,设定初始值为255
	lpDst = (LPBYTE)lpNewDIBBits;
	memset(lpDst, (BYTE)255, lLineBytes * lHeight);
	
	while (bJump)
	{
		bJump = FALSE;
		
		// 初始化新分配的内存,设定初始值为255
		lpDst = (LPBYTE)lpNewDIBBits;
		memset(lpDst, (BYTE)255, lLineBytes * lHeight);

		// 由于使用5×5的结构元素,为防越界,不处理外围的2行、2列像素
		for (i = 2; i < lHeight - 2; i++)
		{
			for (j = 2 * 3; j < lLineBytes - 2 * 3; j += 3)
			{
				// 指向源图像倒数第j行,第i个象素的指针			
				lpSrc = (LPBYTE)(lpDIBBits + lLineBytes * i + j);

				// 指向目标图像倒数第j行,第i个象素的指针			
				lpDst = (LPBYTE)(lpNewDIBBits + lLineBytes * i + j);

				// 如果源图像中当前点为白色,则跳过
				if (*lpSrc > 127)
					continue;

				// 获得当前点相邻的5×5区域内像素值,白色用0代表,黑色用1代表
				for (m = 0; m < 5; m++)
				{
					for (n = 0; n < 5; n++)
					{
						if (*(lpSrc + (2 - m) * lLineBytes + (n - 2) * 3) > 127)
							S[m][n] = 0;
						else
							S[m][n] = 1;
					}
				}

				// 判断条件1-1是否成立:
				nCount =  S[1][1] + S[1][2] + S[1][3] + S[2][1] 
						+ S[2][3] + S[3][1]	+ S[3][2] + S[3][3];

				if (nCount < 2 || nCount >6)
				{
					*lpDst = 0;
					*(lpDst + 1) = 0;
					*(lpDst + 2) = 0;
					continue;
				}

				// 判断条件1-2是否成立:
				nCount = 0;
				
				if (S[1][2] == 0 && S[1][1] == 1) 
					nCount++;
				if (S[1][1] == 0 && S[2][1] == 1)
					nCount++;
				if (S[2][1] == 0 && S[3][1] == 1)
					nCount++;
				if (S[3][1] == 0 && S[3][2] == 1)
					nCount++;
				if (S[3][2] == 0 && S[3][3] == 1)
					nCount++;
				if (S[3][3] == 0 && S[2][3] == 1)
					nCount++;
				if (S[2][3] == 0 && S[1][3] == 1)
					nCount++;
				if (S[1][3] == 0 && S[1][2] == 1)
					nCount++;

				if (nCount != 1)
				{
					*lpDst = 0;
					*(lpDst + 1) = 0;
					*(lpDst + 2) = 0;
					continue;
				}

				// 判断条件1-3是否成立;
				if (S[1][2] * S[2][1] * S[3][2] != 0)
				{
					*lpDst = 0;
					*(lpDst + 1) = 0;
					*(lpDst + 2) = 0;
					continue;
				}

				// 判断条件1-4是否成立:
				if (S[2][1] * S[3][2] * S[2][3] != 0)
				{
					*lpDst = 0;
					*(lpDst + 1) = 0;
					*(lpDst + 2) = 0;
					continue;
				}

				// 如果条件均满足则删除该点
				*lpDst = 255;
				*(lpDst + 1) = 255;
				*(lpDst + 2) = 255;
			}
		}

		// 由于使用5×5的结构元素,为防越界,不处理外围的2行、2列像素
		for (i = 2; i < lHeight - 2; i++)
		{
			for (j = 2 * 3; j < lLineBytes - 2 * 3; j += 3)
			{
				// 指向源图像倒数第j行,第i个象素的指针			
				lpSrc = (LPBYTE)(lpDIBBits + lLineBytes * i + j);

				// 指向目标图像倒数第j行,第i个象素的指针			
				lpDst = (LPBYTE)(lpNewDIBBits + lLineBytes * i + j);

				// 如果源图像中当前点为白色,则跳过
				if (*lpSrc > 127)
					continue;

				// 获得当前点相邻的5×5区域内像素值,白色用0代表,黑色用1代表
				for (m = 0; m < 5; m++)
				{
					for (n = 0; n < 5; n++)
					{
						if (*(lpSrc + (2 - m) * lLineBytes + (n - 2) * 3) > 127)
							S[m][n] = 0;
						else
							S[m][n] = 1;
					}
				}

				// 判断条件2-1是否成立:
				nCount =  S[1][1] + S[1][2] + S[1][3] + S[2][1] 
						+ S[2][3] + S[3][1]	+ S[3][2] + S[3][3];

				if (nCount < 2 || nCount >6)
				{
					*lpDst = 0;
					*(lpDst + 1) = 0;
					*(lpDst + 2) = 0;
					continue;
				}

				// 判断条件2-2是否成立:
				nCount = 0;
				
				if (S[1][2] == 0 && S[1][1] == 1) 
					nCount++;
				if (S[1][1] == 0 && S[2][1] == 1)
					nCount++;
				if (S[2][1] == 0 && S[3][1] == 1)
					nCount++;
				if (S[3][1] == 0 && S[3][2] == 1)
					nCount++;
				if (S[3][2] == 0 && S[3][3] == 1)
					nCount++;
				if (S[3][3] == 0 && S[2][3] == 1)
					nCount++;
				if (S[2][3] == 0 && S[1][3] == 1)
					nCount++;
				if (S[1][3] == 0 && S[1][2] == 1)
					nCount++;

				if (nCount != 1)
				{
					*lpDst = 0;
					*(lpDst + 1) = 0;
					*(lpDst + 2) = 0;
					continue;
				}

				// 判断条件2-3是否成立;
				if (S[1][2] * S[2][1] * S[2][3] != 0)
				{
					*lpDst = 0;
					*(lpDst + 1) = 0;
					*(lpDst + 2) = 0;
					continue;
				}

				// 判断条件2-4是否成立:
				if (S[1][2] * S[3][2] * S[2][3] != 0)
				{
					*lpDst = 0;
					*(lpDst + 1) = 0;
					*(lpDst + 2) = 0;
					continue;
				}

				// 如果条件均满足则删除该点
				*lpDst = 255;
				*(lpDst + 1) = 255;
				*(lpDst + 2) = 255;
				bJump = TRUE;
			}
		}

		// 复制腐蚀后的图像
		memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
	}
	
	// 复制腐蚀后的图像
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);

	// 解除锁定
	::GlobalUnlock((HGLOBAL) hDIB);

	// 释放内存
	LocalUnlock(hNewDIBBits);
	LocalFree(hNewDIBBits);

	// 恢复光标
	EndWaitCursor();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -