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

📄 splitproc.cpp

📁 其中包括图像压缩的基本编码方法如Huffman编码算术编码JPEG 2000H.261压缩编码标准小波变换编码运动估计算法视频图象采集的VC实现等.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// ************************************************************************
//  文件名:SplitProc.cpp
//
//  图像分割处理函数库:
//
//  RgnGrow()				- 区域生长
//	ContourDIB()			- 轮廓提取
//	TraceDIB()				- 边界跟踪
//	Sobel()					- 索贝尔算子的边缘检测
//	Roberts()				- 罗伯特交叉算子的边缘检测
//	Prewitt()				- 蒲瑞维特算子的边缘检测
//	Kirsch()				- Kirsch算子的边缘检测
//	Laplacian()				- 拉普拉斯算子的边缘检测
//	GuassLaplacian()		- 高斯——拉普拉斯算子的边缘检测
//	Hough()					- 哈夫变换检测圆周(r = 40) 
//	Threshold()				- 阀值化区域分割
//
//
// ************************************************************************

#include "stdafx.h"
#include "DIP_System.h"
#include "SplitProc.h"
#include "math.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSplitProc

CSplitProc::CSplitProc()
{
}

CSplitProc::~CSplitProc()
{
}


BEGIN_MESSAGE_MAP(CSplitProc, CWnd)
	//{{AFX_MSG_MAP(CSplitProc)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


////////////////////////////////////////////////////////////////////////////
//							功能模块开始								  //
////////////////////////////////////////////////////////////////////////////

/*************************************************************************
 *
 * 函数名称:
 *   RgnGrow()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *   COLORREF clrSeed_I - 种子点一的RGB值
 *   COLORREF clrSeed_II- 种子点二的RGB值
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *   该函数将彩色位图转化为灰度图像。
 *
 ************************************************************************/

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

	// 指向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);
	float fY_I = (9798.0f * R_I + 19235.0f * G_I + 3735.0f * B_I) / 32768.0f;
	
	// 计算种子点二的灰度值
	unsigned char R_II = GetRValue(clrSeed_II);
	unsigned char G_II = GetGValue(clrSeed_II);
	unsigned char B_II = GetBValue(clrSeed_II);
	float fY_II = (9798.0f * R_II + 19235.0f * G_II + 3735.0f * B_II) / 32768.0f;

	// 锁定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);
			j++;
			unsigned char G = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
			j++;
			unsigned char B = *((unsigned char *)lpDIBBits + lLineBytes * i + j);

			//计算当前点灰度值
			unsigned char Y = (9798 * R + 19235 * G + 3735 * B) / 32768;
			
			if (abs(Y - fY_I) < abs(Y - fY_II))
			{
				//当前点同种子一灰度值比较接近
				
				//将种子一的颜色赋给当前像素
				*((unsigned char *)lpDIBBits + lLineBytes * i + j - 2) = R_I;
				*((unsigned char *)lpDIBBits + lLineBytes * i + j - 1) = G_I;
				*((unsigned char *)lpDIBBits + lLineBytes * i + j ) = B_I;
			}
			else
			{
				//当前点同种子二灰度值比较接近
				
				//将种子二的颜色赋给当前像素
				*((unsigned char *)lpDIBBits + lLineBytes * i + j - 2) = R_II;
				*((unsigned char *)lpDIBBits + lLineBytes * i + j - 1) = G_II;
				*((unsigned char *)lpDIBBits + lLineBytes * i + j ) = B_II;
			}
		}
	}

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

	// 恢复光标
	EndWaitCursor();
}

/*************************************************************************
 *
 * 函数名称:
 *   Sobel()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *	 对图像进行索贝尔算子的边缘检测
 *
 ************************************************************************/

void CSplitProc::Sobel(HDIB hDIB)
{
	// 循环变量
	LONG i;
	LONG j;
	LONG k;
	LONG l;
	
	// 指向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);

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

	// 中间变量
	int v_r_v, v_g_v, v_b_v, g_v;
	int v_r_h, v_g_h, v_b_h, g_h;

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

	// 3X3 模版
	for (i = 0; i < lWidth; i++)			//被处理像素在i列
	{
		for (j = 0; j < lHeight; j++)	//被处理像素在j行
		{
			v_r_v = v_g_v = v_b_v = v_r_h = v_g_h = v_b_h = 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)
					{
						// 检测模版
						if (k == i - 1)
						{
							if (l == j)
								g_v = -2;
							else
								g_v = -1;
						}
						if (k == i + 1)
						{
							if (l == j)
								g_v = 2;
							else
								g_v = 1;
						}
						if (k == i)
							g_v = 0;
						if (l == j - 1)
						{	
							if (k == i)
								g_h = 2;
							else
								g_h = 1;
						}
						if (l == j + 1)
						{
							if (k == i)
								g_h = -2;
							else
								g_h = -1;
						}
						if (l == j)
							g_h = 0;
						
						v_r_v += *(lpDIBBits + l * lLineBytes + k * 3) * g_v;
						v_r_h += *(lpDIBBits + l * lLineBytes + k * 3) * g_h;
						v_g_v += *(lpDIBBits + l * lLineBytes + k * 3 + 1) * g_v;
						v_g_h += *(lpDIBBits + l * lLineBytes + k * 3 + 1) * g_h;
						v_b_v += *(lpDIBBits + l * lLineBytes + k * 3 + 2) * g_v;
						v_b_h += *(lpDIBBits + l * lLineBytes + k * 3 + 2) * g_h;
					}
				}
			}
			m_temp[j * lLineBytes + i * 3] = (int)sqrt(v_r_v * v_r_v + v_r_h * v_r_h);
			m_temp[j * lLineBytes + i * 3 + 1] = (int)sqrt(v_g_v * v_g_v + v_g_h * v_g_h);
			m_temp[j * lLineBytes + i * 3 + 2] = (int)sqrt(v_b_v * v_b_v + v_b_h * v_b_h);
		}
	}

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

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

	// 释放内存
	delete[] m_temp;
	
	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   Prewitt()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *	 对图像进行蒲瑞维特算子的边缘检测
 *
 ************************************************************************/

void CSplitProc::Prewitt(HDIB hDIB)
{
	// 循环变量
	LONG i;
	LONG j;
	LONG k;
	LONG l;
	
	// 指向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);

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

	// 中间变量
	int v_r_v, v_g_v, v_b_v, g_v;
	int v_r_h, v_g_h, v_b_h, g_h;

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

	// 3X3 模版
	for (i = 0; i < lWidth; i++)			//被处理像素在i列
	{
		for (j = 0; j < lHeight; j++)	//被处理像素在j行
		{
			v_r_v = v_g_v = v_b_v = v_r_h = v_g_h = v_b_h = 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)
					{
						// 检测模版
						if (k == i - 1)
							g_v = -1;
						if (k == i + 1)
							g_v = 1;
						if (k == i)
							g_v = 0;
						if (l == j - 1)
							g_h = 1;
						if (l == j + 1)
							g_h = -1;
						if (l == j)
							g_h = 0;
						
						v_r_v += *(lpDIBBits + l * lLineBytes + k * 3) * g_v;
						v_r_h += *(lpDIBBits + l * lLineBytes + k * 3) * g_h;
						v_g_v += *(lpDIBBits + l * lLineBytes + k * 3 + 1) * g_v;
						v_g_h += *(lpDIBBits + l * lLineBytes + k * 3 + 1) * g_h;
						v_b_v += *(lpDIBBits + l * lLineBytes + k * 3 + 2) * g_v;
						v_b_h += *(lpDIBBits + l * lLineBytes + k * 3 + 2) * g_h;
					}
				}
			}
			m_temp[j * lLineBytes + i * 3] = (int)sqrt(v_r_v * v_r_v + v_r_h * v_r_h);
			m_temp[j * lLineBytes + i * 3 + 1] = (int)sqrt(v_g_v * v_g_v + v_g_h * v_g_h);
			m_temp[j * lLineBytes + i * 3 + 2] = (int)sqrt(v_b_v * v_b_v + v_b_h * v_b_h);
		}
	}

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

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

	// 释放内存
	delete[] m_temp;
	
	// 恢复光标
	EndWaitCursor();
}


/*************************************************************************
 *
 * 函数名称:
 *   Roberts()
 *
 * 参数:
 *   HDIB hDIB          - 待处理的DIB
 *
 * 返回值:
 *   void				- 无返回值
 *
 * 说明:
 *	 对图像进行罗伯特交叉算子的边缘检测
 *
 ************************************************************************/

void CSplitProc::Roberts(HDIB hDIB)
{
	// 循环变量
	LONG i;
	LONG j;
	LONG k;
	LONG l;
	
	// 指向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);

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

	// 中间变量
	int v_r_v, v_g_v, v_b_v, g_v;
	int v_r_h, v_g_h, v_b_h, g_h;

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

	// 2X2 模版
	for (i = 0; i < lWidth; i++)		//被处理像素在i列
	{
		for (j = 0; j < lHeight; j++)	//被处理像素在j行
		{
			v_r_v = v_g_v = v_b_v = v_r_h = v_g_h = v_b_h = 0;
			
			for (k = i - 1; k < i + 1; k++)	//2*2模版
			{
				for (l = j - 1; l < j + 1; l++)
				{
					// 防止内存溢出
					if (k >= 0  && l >= 0 && k < lWidth && l < lHeight)
					{
						// 检测模版
						if (k == i - 1 && l == j - 1)
							g_v = 1;
						else if (k == i && l == j)
							g_v = -1;
						else
							g_v = 0;

						if(k == i - 1 && l == j)
							g_h = -1;
						else if (k == i && l == j - 1)
							g_h = 1;
						else
							g_h = 0;
						
						v_r_v += *(lpDIBBits + l * lLineBytes + k * 3) * g_v;
						v_r_h += *(lpDIBBits + l * lLineBytes + k * 3) * g_h;
						v_g_v += *(lpDIBBits + l * lLineBytes + k * 3 + 1) * g_v;
						v_g_h += *(lpDIBBits + l * lLineBytes + k * 3 + 1) * g_h;
						v_b_v += *(lpDIBBits + l * lLineBytes + k * 3 + 2) * g_v;
						v_b_h += *(lpDIBBits + l * lLineBytes + k * 3 + 2) * g_h;
					}
				}
			}
			m_temp[j * lLineBytes + i * 3] = (int)sqrt(v_r_v * v_r_v + v_r_h * v_r_h);
			m_temp[j * lLineBytes + i * 3 + 1] = (int)sqrt(v_g_v * v_g_v + v_g_h * v_g_h);
			m_temp[j * lLineBytes + i * 3 + 2] = (int)sqrt(v_b_v * v_b_v + v_b_h * v_b_h);
		}
	}

⌨️ 快捷键说明

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