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

📄 splitproc.cpp

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

			v_r /= 9;
			v_g /= 9;
			v_b /= 9;

			if (v_r < 0)
				v_r = 0;
			if (v_g < 0)
				v_g = 0;
			if (v_b < 0)
				v_b = 0;

			m_temp[j * lLineBytes + i * 3] = v_r;
			m_temp[j * lLineBytes + i * 3 + 1] = v_g;
			m_temp[j * lLineBytes + i * 3 + 2] = v_b;
		}
	}

	// 回存处理结果到DIB
	memcpy(lpNewDIBBits1, m_temp, lLineBytes * lHeight);

	// 第一图象缓存同第二~第八图象缓存数据依次比较,将
	// 大值保存在第一图象缓存。
	for (int loop = 1; loop < 8; loop++)
	{
		// 复制图象数据到中间缓存
		memcpy(m_temp, lpNewDIBBits2, lLineBytes * lHeight);
	
		// 3X3 模版
		for (i = 0; i < lWidth; i++)		//被处理像素在i列
		{
			for (j = 0; j < lHeight; j++)	//被处理像素在j行
			{
				v_r = v_g = v_b = p_g = 0;
			
				for (k = i - 1; k < i + 2; k++)	//3*3模版
				{
					for (l = j - 1; l < j + 2; l++)
					{
						// 防止内存溢出
						if (k >= 0  && l >= 0 && k < lWidth && l < lHeight)
						{
							v_r += *(lpNewDIBBits2 + l * lLineBytes + k * 3) * g[loop][p_g];
							v_g += *(lpNewDIBBits2 + l * lLineBytes + k * 3 + 1) * g[loop][p_g];
							v_b += *(lpNewDIBBits2 + l * lLineBytes + k * 3 + 2) * g[loop][p_g];
							p_g++;
						}
					}
				}

				v_r /= 9;
				v_g /= 9;
				v_b /= 9;

				if (v_r < 0)
					v_r = 0;
				if (v_g < 0)
					v_g = 0;
				if (v_b < 0)
					v_b = 0;

				m_temp[j * lLineBytes + i * 3] = v_r;
				m_temp[j * lLineBytes + i * 3 + 1] = v_g;
				m_temp[j * lLineBytes + i * 3 + 2] = v_b;
			}
		}

		// 回存处理结果到DIB
		memcpy(lpNewDIBBits2, m_temp, lLineBytes * lHeight);

		// 提取两缓存对应象素的最大值
		for (j = 0; j < lHeight; j++)
		{
			for (i = 0; i < lLineBytes; i++)
			{
				lpDst1 = (LPBYTE)lpNewDIBBits1 + lLineBytes * j + i;
				lpDst2 = (LPBYTE)lpNewDIBBits2 + lLineBytes * j + i;
				if (*lpDst2 > *lpDst1)
					*lpDst1 = * lpDst2;
			}
		}
	}

	// 将检测结果复制到原图象
	memcpy(lpDIBBits, lpNewDIBBits1, lLineBytes * lHeight); 

	// 释放内存、解除锁定
	LocalUnlock(hNewDIBBits1);
	LocalFree(hNewDIBBits1);
	LocalUnlock(hNewDIBBits2);
	LocalFree(hNewDIBBits2);
	::GlobalUnlock((HGLOBAL) hDIB);
	delete[] m_temp;
	
	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   ContourDIB()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *   COLORREF clrSeed_I - 种子点一的RGB值
 *   COLORREF clrSeed_II- 种子点二的RGB值
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图象进行轮廓提取
 *
 ************************************************************************/

void CSplitProc::ContourDIB(HDIB hDIB,COLORREF clrSeed_I,COLORREF clrSeed_II)
{
	// 循环变量
	LONG i;
	LONG j;
	LONG k;
	LONG l;

	// 指向DIB的指针  
	LPBYTE lpDIB;
	
	// 指向DIB象素指针 
	LPBYTE lpDIBBits;
	
	// 计算种子点一的灰度值
	unsigned char R_I = GetRValue(clrSeed_I);
	unsigned char G_I = GetGValue(clrSeed_I);
	unsigned char B_I = GetBValue(clrSeed_I);
	
	// 计算种子点二的灰度值
	unsigned char R_II = GetRValue(clrSeed_II);
	unsigned char G_II = GetGValue(clrSeed_II);
	unsigned char B_II = GetBValue(clrSeed_II);

	unsigned char R, G, B;

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

	// 不能用char,也不能用::strcpy()
	unsigned char* m_temp;
	m_temp = new unsigned char [lLineBytes * lHeight];

	// 复制图象数据到中间缓存
	for (i = 0; i < lLineBytes * lHeight; i++)
		m_temp[i] = *(lpDIBBits + i);

	// 对各像素进行灰度转换
	for (i = 0; i < lWidth; i++)		//被处理像素在i列
	{
		for (j = 0; j < lHeight; j++)	//被处理像素在j行
		{
			int I, II;
			I = II = 0;
			for (k = i - 1; k < i + 2; k++)	//3*3模版
			{
				for (l = j - 1; l < j + 2; l++)
				{
					// 防止内存溢出
					if (k >= 0  && l >= 0 && k < lWidth && l < lHeight)
					{
						// 获取各颜色分量
						R = *((unsigned char *)lpDIBBits + l * lLineBytes + k * 3);
						G = *((unsigned char *)lpDIBBits + l * lLineBytes + k * 3 + 1);
						B = *((unsigned char *)lpDIBBits + l * lLineBytes + k * 3 + 2);
						
						// 判断是否在期望灰度范围内
						if (abs(B - B_I) < 10 && abs(G - B_I) < 10 && abs(R - R_I) < 10)
							I++;
						if (abs(B - B_II) < 10 && abs(G - B_II) < 10 && abs(R - R_II) < 10)
							II++;			
					}
				}
			}
			// 如果周围所有象素灰度相同,当前点一定非边界,可以去掉(设为白色)
			if (I == 9 || II == 9)
			{
				m_temp[j * lLineBytes + i * 3] = 255;
				m_temp[j * lLineBytes + i * 3 + 1] = 255;
				m_temp[j * lLineBytes + i * 3 + 2] = 255;
			}
		}
	}

	// 回存处理结果到DIB
	for(i = 0; i < lLineBytes * lHeight; i++)
		*(lpDIBBits + i) = m_temp[i];

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

	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   TraceDIB()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *   COLORREF clrSeed	- 种子的RGB值 
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图象进行边界跟踪
 *
 ************************************************************************/

void CSplitProc::TraceDIB(HDIB hDIB, COLORREF clrSeed)
{
	// 循环变量
	LONG i;
	LONG j;

	// 指向源图像的指针
	LPBYTE lpSrc;
	
	// 指向缓存图像的指针	
	LPBYTE lpDst;

	//是否找到起始点及回到起始点
	bool bFindStartPoint;

	//是否扫描到一个边界点
	bool bFindPoint;

	//起始边界点与当前边界点
	CPoint StartPoint, CurrentPoint;

	//八个方向和起始扫描方向
	int Direction[8][2] = { {-1, 1}, {0, 1}, {1, 1}, {1, 0},
							{1, -1}, {0, -1}, {-1, -1}, {-1, 0}};
	int BeginDirect;

	// 锁定DIB
	LPBYTE lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);

	// 找到DIB图像象素起始位置
	LPBYTE 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	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);

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

	// 初始化新分配的内存,设定初始值为255
	lpDst = (LPBYTE)lpNewDIBBits;
	memset(lpDst, (BYTE)255, lLineBytes * lHeight);
	
	//先找到最左上方的边界点
	bFindStartPoint = false;

	for (j = 0; j < lHeight && !bFindStartPoint; j++)
	{
		for (i = 0; i < lWidth && !bFindStartPoint; i++)
		{
			// 指向源图像倒数第j行,第i个象素的指针			
			lpSrc = (LPBYTE)(lpDIBBits + lLineBytes * j + i * 3);
			if(abs(*lpSrc - GetRValue(clrSeed)) < 10 && abs(*(lpSrc + 1) - GetGValue(clrSeed)) < 10 && abs(*(lpSrc + 2) - GetBValue(clrSeed)) < 10)
			{
				bFindStartPoint = true;

				StartPoint.y = j;
				StartPoint.x = i;

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

	//由于起始点是在左下方,故起始扫描沿左上方向
	BeginDirect = 0;
	
	//跟踪边界
	bFindStartPoint = false;
	
	//从初始点开始扫描 
	CurrentPoint.y = StartPoint.y;
	CurrentPoint.x = StartPoint.x;
	
	while (!bFindStartPoint)
	{
		bFindPoint = false;
		while (!bFindPoint)
		{
			if ((CurrentPoint.y + Direction[BeginDirect][1]) >= 0
				&& (CurrentPoint.x + Direction[BeginDirect][0]) >= 0
				&& (CurrentPoint.y + Direction[BeginDirect][1]) < lHeight
				&& (CurrentPoint.x + Direction[BeginDirect][0]) < lWidth)
			{

				//沿扫描方向查看一个像素
				lpSrc = (LPBYTE)(lpDIBBits + lLineBytes * (CurrentPoint.y + Direction[BeginDirect][1])
					+ (CurrentPoint.x + Direction[BeginDirect][0]) * 3);
			
				if (abs(*lpSrc - GetRValue(clrSeed)) < 10 && abs(*(lpSrc + 1) - GetGValue(clrSeed)) < 10 && abs(*(lpSrc + 2) - GetBValue(clrSeed)) < 10)
				{
					bFindPoint = true;
					CurrentPoint.y = CurrentPoint.y + Direction[BeginDirect][1];
					CurrentPoint.x = CurrentPoint.x + Direction[BeginDirect][0];
					if (CurrentPoint.y == StartPoint.y && CurrentPoint.x == StartPoint.x)
						bFindStartPoint = true;
					lpDst = (LPBYTE)lpNewDIBBits + lLineBytes * CurrentPoint.y + CurrentPoint.x * 3;
					*lpDst = (unsigned char) 0;
					*(lpDst + 1) = (unsigned char) 0;
					*(lpDst + 2) = (unsigned char) 0;
		
					//扫描的方向逆时针旋转两格
					BeginDirect--;
					if(BeginDirect == -1)
						BeginDirect = 7;
					BeginDirect--;
					if(BeginDirect == -1)
					BeginDirect = 7;
				}
				else
				{
					//扫描方向顺时针旋转一格
					BeginDirect++;
					if(BeginDirect == 8)
						BeginDirect = 0;
				}
			}
			else
			{
				bFindPoint = true;
				bFindStartPoint = true;
			}
		}
	}

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

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

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

	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   Threshold()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *   int T				- 阀值
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数对图象进行阀值化区域分割处理
 *
 ************************************************************************/

void CSplitProc::Threshold(HDIB hDIB, int *nNY)
{
	// 循环变量
	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);

	// 迭代阀值
	int T1, T2;
	T1 = 127;
	T2 = 0;

	// 临时变量
	int Temp0, Temp1, Temp2, Temp3;
	Temp0 = Temp1 = Temp2 = Temp3 = 0;

	while (true)
	{
		// 计算下一个迭代阀值
		for (i = 0; i < T1 + 1; i++)
		{
			Temp0 += nNY[i] * i;
			Temp1 += nNY[i];
		}
		for (i = T1 + 1; i < 256; i++)
		{
			Temp2 += nNY[i] * i;
			Temp3 += nNY[i];
		}
		T2 = (Temp0 / Temp1 + Temp2 / Temp3) / 2;

		// 看迭代结果是否已收敛
		if (T1 == T2)
			break;
		else
			T1 = T2;
	}

	// 对各像素进行灰度转换
	for (i = 0; i < lHeight; i ++)
	{
		for (j = 0; j < lLineBytes; j ++)
		{
			// 读取像素R分量
			unsigned char R = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			
			// 判断R分量是否超出范围
			if (R < T1)
				R = 0;
			else
				R = 255;
			
			// 回写处理完的R分量
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = R;
			j++;

			// 读取像素G分量
			unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			
			// 判断G分量是否超出范围
			if (G < T1)
				G = 0;
			else 
				G = 255;
			
			// 回写处理完的G分量
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = G;
			j++;

			// 读取像素B分量
			unsigned char B = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			
			// 判断B分量是否超出范围
			if (B < T1)
				B = 0;
			else
				B = 255;
			
			// 回写处理完的B分量
			*((unsigned char *)lpDIBBits + lLineBytes * i + j) = B;
		}
	}

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

	// 恢复光标
	EndWaitCursor();
}

⌨️ 快捷键说明

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