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

📄 bmpproc.cpp

📁 运用BP网络实现三个二进制位的异或运算,带有样本库可编译运行
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// BmpProc.cpp : implementation file
//

#include "stdafx.h"
#include "神经网络作业.h"
#include "BmpProc.h"
#include "神经网络作业Doc.h"

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

/////////////////////////////////////////////////////////////////////////////
// CBmpProc

CBmpProc::CBmpProc()
{
}

CBmpProc::~CBmpProc()
{
}


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


/////////////////////////////////////////////////////////////////////////////
// CBmpProc message handlers
void CBmpProc::ToGray(HDIB hDIB)
{
		LPBYTE	lpDIB;
			
		// 由DIB句柄得到DIB指针并锁定DIB
		lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL)hDIB);
			
		// 指向DIB象素数据区的指针
		LPBYTE   lpDIBBits;	

		// 指向DIB象素的指针
		BYTE *	lpSrc;	

		// 图像宽度
		LONG	lWidth;	
		// 图像高度
		LONG  	lHeight;	

		// 图像每行的字节数
		LONG	lLineBytes;	

		// 指向BITMAPINFO结构的指针(Win3.0)
		LPBITMAPINFO lpbmi;	

		// 指向BITMAPCOREINFO结构的指针
		LPBITMAPCOREINFO lpbmc;
			
		// 获取指向BITMAPINFO结构的指针(Win3.0)
		lpbmi = (LPBITMAPINFO)lpDIB;	

		// 获取指向BITMAPCOREINFO结构的指针
		lpbmc = (LPBITMAPCOREINFO)lpDIB;	

		// 灰度映射表
		BYTE bMap[256];
			
		// 计算灰度映射表(保存各个颜色的灰度值),并更新DIB调色板
		int	i,j;
		for (i = 0; i < 256; i ++)
			{
				// 计算该颜色对应的灰度值
				bMap[i] = (BYTE)(0.299 * lpbmi->bmiColors[i].rgbRed +

								 0.587 * lpbmi->bmiColors[i].rgbGreen +

								 0.114 * lpbmi->bmiColors[i].rgbBlue + 0.5);			
				// 更新DIB调色板红色分量
				lpbmi->bmiColors[i].rgbRed = i;	
				
				// 更新DIB调色板绿色分量
				lpbmi->bmiColors[i].rgbGreen = i;	
				
				// 更新DIB调色板蓝色分量
				lpbmi->bmiColors[i].rgbBlue = i;
					
				// 更新DIB调色板保留位
				lpbmi->bmiColors[i].rgbReserved = 0;

			}
			// 找到DIB图像象素起始位置
		lpDIBBits =m_clsDIB.FindDIBBits(lpDIB);;

		// DIB的宽度
		lWidth = m_clsDIB.DIBWidth(lpDIB);
	
		// DIB的高度
		lHeight = m_clsDIB.DIBHeight(lpDIB);	

		// 计算图像每行的字节数
		lLineBytes = WIDTHBYTES(lWidth * 8);	

		// 更换每个象素的颜色索引(即按照灰度映射表换成灰度值)

		//逐行扫描
		for(i = 0; i < lHeight; i++)
		{

		  //逐列扫描
			for(j = 0; j < lWidth; j++)
				{
					// 指向DIB第i行,第j个象素的指针
					lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
							
					// 变换
					*lpSrc = bMap[*lpSrc];
				}
		}

		//解除锁定
		::GlobalUnlock ((HGLOBAL)hDIB);
}
void CBmpProc::ConvertToWBlk(HDIB hDIB)
{
		// 指向DIB的指针
	LPBYTE	lpDIB;
	
	// 由DIB句柄得到DIB指针并锁定DIB
	lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL)hDIB);
	
	// 指向DIB象素数据区的指针
	LPBYTE   lpDIBBits;
	
	// 指向DIB象素的指针
	BYTE *	lpSrc;	

	// 图像宽度
	LONG	lWidth;	

	// 图像高度
	LONG	lHeight;	
	// 图像每行的字节数
	LONG	lLineBytes;	

	// 找到DIB图像象素起始位置
	lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);	
	
	// 获取图像宽度
	lWidth = m_clsDIB.DIBWidth(lpDIB);	

	// 获取图像高度
	lHeight = m_clsDIB.DIBHeight(lpDIB);	

	// 计算图像每行的字节数
	lLineBytes = WIDTHBYTES(lWidth * 8);	

	// 更换每个象素的颜色索引(即按照灰度映射表换成灰度值)
	int i,j;

    //逐行扫描
	for(i = 0; i < lHeight; i++)
	{

	   //逐列扫描
		for(j = 0; j < lWidth; j++)
		{

		// 指向DIB第i行,第j个象素的指针
		lpSrc = (unsigned char*)lpDIBBits + lLineBytes * i + j;

		// 二值化处理

	   //大于220,设置为255,即白点
		if(*lpSrc>220) *lpSrc=255;

	  //否则设置为0,即黑点
		else *lpSrc=0;
		}

	}
	
	//解除锁定
	::GlobalUnlock((HGLOBAL)hDIB);
}
void CBmpProc::Sharp(HDIB hDIB)
{
	// 指向DIB的指针
	LPBYTE lpDIB=(LPBYTE) ::GlobalLock((HGLOBAL)hDIB);

	// 指向DIB象素指针
	LPBYTE lpDIBBits;	

	// 找到DIB图像象素起始位置
	lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
	

    //获取图像的宽度
	LONG lWidth= m_clsDIB.DIBWidth (lpDIB);

    //获取图像的长度
	LONG lHeight= m_clsDIB.DIBHeight (lpDIB);

    // 阈值
	BYTE	bThre = 2;

	// 调用GradSharp()函数进行梯度板锐化

	// 指向源图像的指针
	unsigned char*	lpSrc;
	unsigned char*	lpSrc1;
	unsigned char*	lpSrc2;
	
	// 循环变量
	LONG	i;
	LONG	j;
	
	// 图像每行的字节数
	LONG	lLineBytes;
	
	// 中间变量
	BYTE	bTemp;
	
	// 计算图像每行的字节数
	lLineBytes = WIDTHBYTES(lWidth * 8);
	
	// 每行
   for(i = 0; i < lHeight; i++)
	{
		
     // 每列
	 for(j = 0; j < lWidth; j++)
		{
			
             // 指向DIB第i行,第j个象素的指针
			lpSrc  = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
			
			// 指向DIB第i+1行,第j个象素的指针
			lpSrc1 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 2 - i) + j;
			
		     // 指向DIB第i行,第j+1个象素的指针
		     lpSrc2 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j + 1;
			

              //计算梯度值
		     bTemp = abs((*lpSrc)-(*lpSrc1)) + abs((*lpSrc)-(*lpSrc2));
			
		    // 判断是否小于阈值
		    if (bTemp < 255)
			{  

		     // 判断是否大于阈值,对于小于情况,灰度值不变。
			   if (bTemp >= bThre)
			   {

			// 直接赋值为bTemp
			 *lpSrc = bTemp;

			   }

			}
			
           else
			{
				// 直接赋值为255
				*lpSrc = 255;
			}
	 }
   }

	//最后还要处理一下图像中最下面那行
	for(j = 0; j < lWidth; j++)
	{   
		
	 //指向最下边一行,第j个象素的指针
	  lpSrc  = (unsigned char*)lpDIBBits + lLineBytes * 0 + j;

	   //将此位置的象素设置为255,即白点
		*lpSrc=255;
	}

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

void CBmpProc::Denoise(HDIB hDIB)
{
	
	// 指向DIB的指针
	LPBYTE lpDIB=(LPBYTE) ::GlobalLock((HGLOBAL)hDIB);
	
	// 指向DIB象素指针
	LPBYTE lpDIBBits;	

	// 找到DIB图像象素数据区的起始位置
	lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
	
	//获得图像的长度
	LONG lWidth= m_clsDIB.DIBWidth (lpDIB);

	//获得图像的高度
	LONG lHeight= m_clsDIB.DIBHeight (lpDIB);

	//设置判定噪声的长度阈值为15
	//即如果与考察点相连接的黑点的数目小于15则认为考察点是噪声点
	int length=15;
	
	// 循环变量
	m_lianXuShu=0;
	LONG	i;
	LONG	j;	
	LONG    k;

	// 图像每行的字节数
	LONG lLineBytes;

	// 计算图像每行的字节数
	lLineBytes = WIDTHBYTES(lWidth * 8);

    
	LPSTR lpSrc;

	//开辟一块用来存放标志的内存数组
	LPBYTE lplab = new BYTE[lHeight * lWidth];

	//开辟一块用来保存离散判定结果的内存数组
	bool *lpTemp = new bool[lHeight * lWidth];

    //初始化标志数组
	for (i=0;i<lHeight*lWidth;i++)
    {

		//将所有的标志位设置为非
		lplab[i] = false;

	}

	//用来存放离散点的坐标的数组
	CPoint lab[21];
   
	//为循环变量赋初始值
	k=0;

	//扫描整个图像

	//逐行扫描
	for(i =0;i<lHeight;i++)
	{  
       
	   //逐行扫描
		for(j=0;j<lWidth;j++)
			{	
				//先把标志位置false
				for(k=0;k<m_lianXuShu;k++)
				lplab[lab[k].y * lWidth + lab[k].x] = false;

				//连续数置0
				m_lianXuShu =0;

			    //进行离散性判断
			    lpTemp[i*lWidth+j] = DeleteScaterJudge(lpDIBBits,(WORD)lLineBytes,lplab,lWidth,lHeight,j,i,lab,length);

			}
	}
			
	//扫描整个图像,把离散点填充成白色

	//逐行扫描
	for(i = 0;i<lHeight;i++)
	{

      //逐列扫描
		for(j=0;j<lWidth;j++)
		{       
			    //查看标志位,如果为非则将此点设为白点
				if(lpTemp[i*lWidth+j] == false)
				{	
                   //指向第i行第j个象素的指针
					lpSrc=(char*)lpDIBBits + lLineBytes * i + j;

					//将此象素设为白点
					*lpSrc=BYTE(255);
				}
			}
	}

	//解除锁定
	::GlobalUnlock ((HGLOBAL)hDIB);
	
}
bool CBmpProc::DeleteScaterJudge(LPBYTE lpDIBBits, WORD lLineBytes, LPBYTE lplab, int lWidth, int lHeight, int x, int y, CPoint lab[], int lianXuShu)
{
	
	//如果连续长度满足要求,说明不是离散点,返回
	if(m_lianXuShu>=lianXuShu)
		return TRUE;

	//长度加一
	m_lianXuShu++;

	//设定访问标志
	lplab[lWidth * y +x] = true;
	
	//保存访问点坐标
	lab[m_lianXuShu-1].x = x;
	lab[m_lianXuShu-1].y = y;

	//象素的灰度值
	int gray;
  
	//指向象素的指针
	LPSTR lpSrc;

	//长度判定
    //如果连续长度满足要求,说明不是离散点,返回
	if(m_lianXuShu>=lianXuShu)
		return TRUE;
	
	//下面进入递归
	else
	{	
		//考察上下左右以及左上、右上、左下、右下八个方向
		//如果是黑色点,则调用函数自身进行递归

		//考察下面点
		
		lpSrc=(char*)lpDIBBits + lLineBytes * (y-1) + x;

		//传递灰度值
		gray=*lpSrc;

		//如果点在图像内、颜色为黑色并且没有被访问过
		if(y-1 >=0 && gray == 0 && lplab[(y-1)*lWidth+x] == false)

		//进行递归处理		
		DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x,y-1,lab,lianXuShu);

		//判断长度
		//如果连续长度满足要求,说明不是离散点,返回
		if(m_lianXuShu>=lianXuShu)
		return TRUE;
		
		//左下点
		
		lpSrc=(char*)lpDIBBits + lLineBytes * (y-1) + x-1;

        //传递灰度值
		gray=*lpSrc;

        //如果点在图像内、颜色为黑色并且没有被访问过
		if(y-1 >=0 &&  x-1 >=0 && gray== 0 && lplab[(y-1)*lWidth+x-1] == false)

      	//进行递归处理		
		DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x-1,y-1,lab,lianXuShu);

        //判断长度
		//如果连续长度满足要求,说明不是离散点,返回
		if(m_lianXuShu>=lianXuShu)
		return TRUE;
		
		//左边
		
		lpSrc=(char*)lpDIBBits + lLineBytes * y + x-1;

		//传递灰度值
		gray=*lpSrc;

        //如果点在图像内、颜色为黑色并且没有被访问过
		if(x-1 >=0 &&  gray== 0 && lplab[y*lWidth+x-1] == false)

        //进行递归处理		
		DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x-1,y,lab,lianXuShu);

        //判断长度
		//如果连续长度满足要求,说明不是离散点,返回
		if(m_lianXuShu>=lianXuShu)
			return TRUE;
		
		//左上
		
		lpSrc=(char*)lpDIBBits + lLineBytes * (y+1) + x-1;

		//传递灰度值
		gray=*lpSrc;

        //如果点在图像内、颜色为黑色并且没有被访问过
		if(y+1 <lHeight && x-1 >= 0 && gray == 0 && lplab[(y+1)*lWidth+x-1] == false)

		//进行递归处理
		
		DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x-1,y+1,lab,lianXuShu);

        //判断长度
		//如果连续长度满足要求,说明不是离散点,返回
		if(m_lianXuShu>=lianXuShu)
			return TRUE;
		
		//上面
		
		lpSrc=(char*)lpDIBBits + lLineBytes * (y+1) + x;

        //传递灰度值
		gray=*lpSrc;

        //如果点在图像内、颜色为黑色并且没有被访问过
		if(y+1 < lHeight && gray == 0 && lplab[(y+1)*lWidth+x] == false)

        //进行递归处理
		
		DeleteScaterJudge(lpDIBBits,lLineBytes,lplab,lWidth,lHeight,x,y+1,lab,lianXuShu);

        //判断长度
		//如果连续长度满足要求,说明不是离散点,返回
		if(m_lianXuShu>=lianXuShu)
			return TRUE;
		
		//右上
		
		lpSrc=(char*)lpDIBBits + lLineBytes * (y+1) + x+1;

⌨️ 快捷键说明

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