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

📄 areapro.cpp

📁 用C++实现的数字图像处理各个算法源代码 我精心整理的 很难的啊 希望可以给大家带来帮助
💻 CPP
📖 第 1 页 / 共 5 页
字号:

	//坐标规整化
	m_pDibObject->NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2 );

	//获取图像宽度和高度(以像素为单位)
	int nWidth = m_pDibObject->GetWidth();
	int nHeight = m_pDibObject->GetHeight();

	//对边界像素不作处理
	if( nX1 < nTempXc ) nX1 = nTempXc;
	if( nY1 < nTempYc ) nY1 = nTempYc;
	if( nX2 > nWidth - nTempW + nTempXc + 1) nX2 = nWidth - nTempW + nTempXc + 1;
	if( nY2 > nHeight - nTempH + nTempYc + 1) nY2 = nHeight - nTempH + nTempYc + 1;

	//定义变量
	unsigned char *pBuffer, *pBits;
	RGBQUAD *pPalette;
	int nWidthBytes, nNewWidthBytes, nNumColors;
	DWORD dwNewSize;

	//获得图像指针
	pBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes, 
		                                       m_pDibObject->GetNumBits(),
											   &nNewWidthBytes, 8);
	if( pBuffer == NULL ) return( NULL );

	//获得颜色数
	nNumColors = m_pDibObject->GetNumColors();
	//获得调色板指针
	pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)];
	//获得位图数据指针
	pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
		                               + nNumColors * sizeof(RGBQUAD)];

	dwNewSize = nNewWidthBytes * nHeight;

	//定义用于存储色相值的临时数组
	double *pHue = new double [dwNewSize];
	if(pHue == NULL) return(FALSE);
	memset(pHue, 0, dwNewSize * sizeof(double));

	//定义用于存储饱和度值的临时数组
	double *pSaturation = new double [dwNewSize];
	if(pSaturation == NULL) return(FALSE);
	memset(pSaturation, 0, dwNewSize * sizeof(double));

	//定义用于存储亮度值的临时数组
	unsigned char *pLight = new unsigned char [dwNewSize];
	if(pLight == NULL) return(FALSE);
	memset(pLight, 0, dwNewSize * sizeof(unsigned char));

	float *fTempArray;

	//默认为3×3的高通滤波器1模板
	static float fpDefaultArray[] = {-1.0, -1.0, -1.0, 
							         -1.0,  9.0, -1.0,
							         -1.0, -1.0, -1.0};

	//没有传入模板,用默认模板
	if( fpArray == NULL ) fTempArray = fpDefaultArray;
	//采用传入的模板
	else fTempArray = fpArray;

	//调用Template操作函数
	if(!TemplateOperation(fTempArray, fCoef, nTempW, nTempH, nTempXc, nTempYc,
						pBits, nWidthBytes, nX1, nY1, nX2, nY2))
	{
		return(FALSE);
	}

	//内存解锁
	::GlobalUnlock(m_pDibObject->GetDib());

	return( TRUE );
}

////////////////////////////////////////////////////////////////////////
//BOOL MedianFilter()   
//----------------------------------------------------------------------
//基本功能:本函数对传入的CDibObject图像对象进行中值滤波。任何未指定的或
//			默认为-1的坐标将被置为图像的边缘值。比如:nX1和nY1会被置为0;
//			nX2和nY2会被置为图像的宽和高。对整个图像进行中值滤波的最好方
//			法是不传递任何参数。如果不指定一个CDibObject对象指针,函数将
//			使用原先传入的CDibObject对象指针。
//----------------------------------------------------------------------
//参数说明:int	  nType		获取中值的方式, 默认为1
//								0——冒泡排序
//								1——数组排序
//			int   nTempW	窗口的宽度
//			int   nTempH	窗口的高度
//			int   nTempXc	窗口的中心元素X坐标
//			int   nTempYc	窗口的中心元素Y坐标
//			int	  nX1		默认为-1
//			int   nY1		默认为-1
//			int	  nX2		默认为-1
//			int	  nY2		默认为-1
//					
//----------------------------------------------------------------------
//返    回:BOOL
//			成功时返回TRUE,失败时返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CAreaPro::MedianFilter(int nType, int nTempW, int nTempH, int nTempXc, 
							int nTempYc, int nX1, int nY1, int nX2, int nY2)
{
   //图像指针为空,无法操作返回
	if(m_pDibObject == NULL) return(FALSE);
	
	//对1位及4位图像不作任何操作直接返回
	if(m_pDibObject->GetNumBits() != 8)
	{
		// 提示用户参数设置错误
		AfxMessageBox("只支持8位图像,请重新载入!");
		
		// 返回
		return( FALSE );
	}
	
	//坐标规整化
	m_pDibObject->NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2 );
	
	//获取图像宽度和高度(以像素为单位)
	int nWidth = m_pDibObject->GetWidth();
	int nHeight = m_pDibObject->GetHeight();
	
	//对边界像素不作处理
	if( nX1 < nTempXc ) nX1 = nTempXc;
	if( nY1 < nTempYc ) nY1 = nTempYc;
	if( nX2 >= nWidth - nTempW + nTempXc) nX2 = nWidth - nTempW + nTempXc + 1;
	if( nY2 >= nHeight - nTempH + nTempYc) nY2 = nHeight - nTempH + nTempYc + 1;
	
	//定义变量
	unsigned char Data;
	//定义与图像数据操作有关的变量
	unsigned char *pOldBuffer, *pNewBuffer, 
				  *pOldBits, *pNewBits, 
				  *pOldTemp, *pNewTemp,
				  *pNeighborTemp;

	BITMAPFILEHEADER *pOldBFH, *pNewBFH;

	BITMAPINFOHEADER *pOldBIH, *pNewBIH;

	RGBQUAD *pOldPalette, *pNewPalette;

	int nWidthBytes, nNumColors, x, y, i, j;
	
	//获取原图像指针
	pOldBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes, 
												m_pDibObject->GetNumBits() );
	if( pOldBuffer == NULL ) return( FALSE );
	
	//原图像文件头
	pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
	//原图像信息头
	pOldBIH = (BITMAPINFOHEADER *) &pOldBuffer[sizeof(BITMAPFILEHEADER)];
	//原图像颜色数
	nNumColors = m_pDibObject->GetNumColors();
	//原图像调色板指针
	pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)];
	//原图像数据指针
	pOldBits = (unsigned char *) &pOldBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
											 + nNumColors * sizeof(RGBQUAD)];
	
	DWORD dwNewSize;
	HGLOBAL hNewDib;
	
	//新图像文件大小(以字节为单位)
	dwNewSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + 
				nNumColors * sizeof( RGBQUAD ) + nWidthBytes * nHeight;

	//为新图像分配内存
	hNewDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );

	//内存分配失败
	if( hNewDib == NULL )
	{
		m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
		::GlobalUnlock( m_pDibObject->GetDib() );
		return( FALSE );
	}
	
	//新图像指针
	pNewBuffer = (unsigned char *) ::GlobalLock( hNewDib );
	if( pNewBuffer == NULL )
	{
		::GlobalFree( hNewDib );
		m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
		::GlobalUnlock( m_pDibObject->GetDib() );
		return( FALSE );
	}
	
	//新图像文件头
	pNewBFH = (BITMAPFILEHEADER *) pNewBuffer;
	//新图像信息头
	pNewBIH = (BITMAPINFOHEADER *) &pNewBuffer[sizeof(BITMAPFILEHEADER)];
	//新图像调色板指针
	pNewPalette = (RGBQUAD *) &pNewBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)];
	//新图像数据指针
	pNewBits = (unsigned char *) &pNewBuffer[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
											 + nNumColors*sizeof(RGBQUAD)];
	
	//复制原图像数据到新图像

	//复制文件头
	memcpy(pNewBFH, pOldBFH, sizeof(BITMAPFILEHEADER));
	
	//复制信息头
	memcpy(pNewBIH, pOldBIH, sizeof(BITMAPINFOHEADER));
	
	//复制调色板
	for(i = 0; i < nNumColors; i++ ) pNewPalette[i] = pOldPalette[i];
	
	//复制图像数据
	memcpy( pNewBits, pOldBits, nWidthBytes * nHeight );

	//计算模板的尺寸
	int nSize = nTempW * nTempH;
	
	//定义查找中值用的临时数组
	unsigned char *pGray = new unsigned char [nTempW * nTempH];
	if(pGray == NULL) return( NULL );
	memset(pGray, 0, (nSize) * sizeof(unsigned char));

	unsigned char nData;

	switch(m_pDibObject->GetNumBits())
	{
	case 8:			//8位图像
		//行位置
		for(y = nY1; y < nY2; y++ )
		{
			//原图像数据指针定位到起始位置
			pOldTemp = pOldBits;
			//原图像数据指针定位到图像数据每行的起始零位置
			pOldTemp += (nHeight - 1 - y) * nWidthBytes;
			//原图像数据指针定位到图像数据每行的起始nX1位置
			pOldTemp += nX1;
			
			//新图像数据指针定位到起始位置
			pNewTemp = pNewBits;
			//新图像数据指针定位到图像数据每行的起始零位置
			pNewTemp += (nHeight - 1 - y) * nWidthBytes;
			//新图像数据指针定位到图像数据每行的起始nX1位置
			pNewTemp += nX1;
			
			//列位置
			for(x = nX1; x < nX2; x++)
			{
				//取出原图像nTempW×nTempH邻域内的像素值
				for (i = 0; i < nTempH; i++)
				{
					for (j = 0; j < nTempW; j++)
					{
						//数据指针指向当前像素
						pNeighborTemp = pOldTemp;
						//数据指针指向原图像第y - nTempYc + i行。
						pNeighborTemp += nWidthBytes * (nTempYc - i);
						//第x - nTempXc + j列像素的指针
						pNeighborTemp += (j - nTempXc);
						
						//获取像素值
						Data = *pNeighborTemp;

						pGray[i*nTempW+j] = ( pOldPalette[Data].rgbRed * 30 +
										pOldPalette[Data].rgbGreen * 59 +
										pOldPalette[Data].rgbBlue * 11 ) / 100;
					}
				}
				
				nData = GetMedian(pGray, nSize, nType);
				//将计算结果赋于新图像
				*pNewTemp = (unsigned char) m_pDibObject->GetNearestIndex( 
					pNewPalette[nData].rgbRed, pNewPalette[nData].rgbGreen, 
					pNewPalette[nData].rgbBlue,	pNewPalette, nNumColors );

				//新旧图像数据指针加1
				pOldTemp++;
				pNewTemp++;
				
			}
		}
		break;
	}
	
	//释放内存
	delete [] pGray;

	::GlobalUnlock( m_pDibObject->GetDib() );
    ::GlobalFree( m_pDibObject->GetDib() );
	::GlobalUnlock( hNewDib );
    m_pDibObject->SetDib( hNewDib );
    return(TRUE);
}

////////////////////////////////////////////////////////////////////////
//BOOL TemplateOperation()   
//----------------------------------------------------------------------
//基本功能:该函数用指定的模板(任意大小)来对图像数据区的数据进行模板操
//			作,参数nTempH指定模板的高度,参数nTempW指定模板的宽度,参数
//			nTempXc和nTempYc指定模板的中心元素坐标,参数fpArray为指定模
//			板元素数组的指针,fCoef指定模板系数。
//----------------------------------------------------------------------
//参数说明:float *fpArray			指向模板数组的指针
//			float fCoef				模板系数
//			int   nTempW			模板的宽度
//			int   nTempH			模板的高度
//			int   nTempXc			模板的中心元素X坐标 ( <= nTempW - 1)
//			int   nTempYc			模板的中心元素Y坐标 ( <= nTempH - 1)
//			unsigned char *pData	图像数据指针
//			int nWidthBytes			图像字节宽度
//			int	  nX1				处理区域左边界		
//			int   nY1				处理区域上边界
//			int	  nX2				处理区域右边界
//			int	  nY2				处理区域下边界
//----------------------------------------------------------------------
//返    回:BOOL
//			成功时返回TRUE,失败时返回FALSE。
//----------------------------------------------------------------------
//注    意:此函数声明为保护型,只能在CAreaPro类中使用。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CAreaPro::TemplateOperation(float *fpArray, float fCoef, 
						int nTempW, int nTempH, int nTempXc, int nTempYc,
						unsigned char *pData, int nWidthBytes, 
						int nX1, int nY1, int nX2, int nY2)
{
	//获取图像高度(以像素为单位)
	int nHeight = m_pDibObject->GetHeight();

	//定义变量
	unsigned char Data;

	//定义与图像数据操作有关的变量
	unsigned char *pOldBits, *pNewBits, 
				  *pOldTemp, *pNewTemp,
				  *pNeighborTemp;
	int nNumColors, x, y, i, j;
	DWORD dwNewSize;

	//原图像颜色数
	nNumColors = m_pDibObject->GetNumColors();

	//原图像数据指针
	pOldBits = pData;

	HGLOBAL hNewDib;

	//新图像文件大小(以字节为单位)
	dwNewSize = nWidthBytes * nHeight;
	//为新图像分配内存
	hNewDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
	//内存分配失败
	if( hNewDib == NULL )
	{
		m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
		::GlobalUnlock( m_pDibObject->GetDib() );
		return( FALSE );
	}

	//新图像指针
	pNewBits = (unsigned char *) ::GlobalLock( hNewDib );
	if( pNewBits == NULL )
	{
		::GlobalFree( hNewDib );
		m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
		return( FALSE );
	}

	//复制图像数据
	memcpy( pNewBits, pOldBits, nWidthBytes * nHeight );

	//定义卷积运算中用的临时数组
	float *pGray = new float [nTempW * nTempH];
	if(pGray == NULL) return( NULL );
	memset(pGray, 0, (nTempW * nTempH) * sizeof(float));
	
	//行位置
	for(y = nY1; y < nY2; y++ )
	{
		//原图像数据指针定位到起始位置
		pOldTemp = pOldBits;
		//原图像数据指针定位到图像数据每行的起始零位置
		pOldTemp += (nHeight -1 - y) * nWidthBytes;
		//原图像数据指针定位到图像数据每行的起始nX1-1位置
		pOldTemp += nX1;
		
		//新图像数据指针定位到起始位置
		pNewTemp = pNewBits;
		//新图像数据指针定位到图像数据每行的起始零位置
		pNewTemp += (nHeight -1 - y) * nWidthBytes;
		//新图像数据指针定位到图像数据每行的起始nX1位置
		pNewTemp += nX1;
		
		//列位置
		for(x = nX1; x < nX2; x++)
		{
			//取出原图像nTempW×nTempH邻域内的像素值
			for (i = 0; i < nTempH; i++)
			{
				for (j = 0; j < nTempW; j++)
				{
					//数据指针指向当前像素
					pNeighborTemp = pOldTemp;
					//数据指针指向原图像第y - nTempYc + i行。

⌨️ 快捷键说明

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