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

📄 bmpproc.cpp

📁 运用BP网络实现三个二进制位的异或运算,带有样本库可编译运行
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        
		//传递灰度值
		gray=*lpSrc;

        //如果点在图像内、颜色为黑色并且没有被访问过
		if(y+1 <lHeight && x+1 <lWidth &&  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 <lWidth && 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 >=0 && x+1 <lWidth && 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;
	}
	

	//如果递归结束,返回false,说明是离散点
	return FALSE;

}

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

	// 找到DIB图像象素起始位置
	lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);
	
	// 指向源图像的指针
	unsigned char*	lpSrc;

	// 循环变量
	LONG	i;
	LONG	j;
	
	// 图像每行的字节数
	LONG	lLineBytes;

	//图像的长度
	LONG    lWidth;

	//图像的宽度
	LONG	lHeight;

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

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

	// 计算图像每行的字节数
	lLineBytes = WIDTHBYTES(lWidth * 8);
    
	//图像左半边的平均高度
	double leftaver=0.0;

   //图像右半边的平均高度
	double rightaver=0.0;

	//图像的倾斜度
	double slope;

	//统计循环变量
	LONG counts=0;
	
	//扫描左半边的图像,求黑色象素的平均高度

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

      //列
		for (j=0;j<lWidth/2;j++)
		{
		 
		 //指向第i行第j个象素的指针	
		 lpSrc=(unsigned char*)lpDIBBits + lLineBytes *  i + j;
      
		 //如果为黑点
		 if (*lpSrc == 0)
		 {
          
          //对其高度进行统计叠加
		  counts +=lWidth/2 -j;
		  leftaver += i*(lWidth/2 -j);

		 }

		}
	}

    //计算平均高度
	leftaver /= counts;
	
	//将统计循环变量重新赋值
	counts =0;

	//扫描右半边的图像,求黑色象素的平均高度

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

       //列
		for (j=lWidth/2;j<lWidth;j++)
		{
			//指向第i行第j个象素的指针
			lpSrc=(unsigned char*)lpDIBBits + lLineBytes *  i + j;

            //如果为黑点
			if (*lpSrc == 0)
				{

				  //进行统计叠加
					counts +=lWidth -j;
					rightaver += i*(lWidth -j);
				}
			}
	}

	//计算右半边的平均高度
	rightaver /= counts;
	
	//计算斜率
	slope = (leftaver - rightaver) / (lWidth/2);

	//指向新的图像象素起始位置的指针
	LPSTR lpNewDIBBits;
   
	//指向新图像的指针
	LPSTR lpDst;
    
	//新图像的句柄
	HLOCAL nNewDIBBits=LocalAlloc(LHND,lLineBytes*lHeight);
    
	//锁定内存
	lpNewDIBBits=(char*)LocalLock(nNewDIBBits);
    
	//指向新图像象素的指针
	lpDst=(char*)lpNewDIBBits;
    
	//为新图像赋初始值
	memset(lpDst,(BYTE)255,lLineBytes*lHeight);
    
	//象素点的灰度值
	int gray;
    
	//位置映射值
	int i_src;

	//根据斜率,把当前新图像的点映射到源图像的点

	//行
	for (i=0;i<lHeight;i++)
	{
		//列
   		for (j=0;j<lWidth;j++)
		{	
		   //计算映射位置	
			i_src=int(i - (j-lWidth/2)*slope);

			//如果点在图像外,象素置白色
			if (i_src <0 || i_src >=lHeight )
				gray = 255;

			else
			{	
				//否则到源图像中找点,取得象素值

				//指向第i_src行第j个象素的指针
				lpSrc=(unsigned char *)lpDIBBits + lLineBytes *  i_src + j;
				gray = *lpSrc;
			}
			
			//把新图像的点用得到的象素值填充
            //指向第i行第j个象素的指针
			lpDst = (char *)lpNewDIBBits + lLineBytes * i + j;
			*lpDst=gray;
		}
	}

	// 将新的图像的内容拷贝到旧的图像中
	memcpy(lpDIBBits,lpNewDIBBits,lLineBytes*lHeight);

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

CRectLink CBmpProc::CharSegment(HANDLE hDIB)
{
	
	//清空用来保存每个字符区域的链表
	CRectLink charRect1,charRect2;
	charRect1.clear();
	charRect2.clear();

	// 指向DIB的指针
	LPSTR lpDIB=(LPSTR) ::GlobalLock((HGLOBAL)hDIB);
	
	// 指向DIB象素指针
	LPSTR    lpDIBBits;	

	// 找到DIB图像象素起始位置
	lpDIBBits = ::FindDIBBits(lpDIB);
	
	//指向象素的的指针
	BYTE* lpSrc;

	//图像的长度和宽度
	int height,width;

	//获取图像的宽度
	width=(int)::DIBWidth(lpDIB);

	//获取图像的长度
	height=(int)::DIBHeight(lpDIB);

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

	//定义上下边界两个变量
	int top,bottom;

    //象素的灰度值
    int gray; 

	//设置循环变量
	int i,j;

	//用来统计图像中字符个数的计数器
	digicount=0;


	//从上往下扫描,找到上边界

	//行
	for (i=0;i<height;i++)
	{
         //列
  		for (j=0;j<width;j++)
		{
            // 指向图像第i行,第j个象素的指针
			lpSrc = (unsigned char*)lpDIBBits + lLineBytes * i + j;

			//获得该点的灰度值
			gray = *(lpSrc);

			//看是否为黑点
			if (gray == 0)
			{   
               //若为黑点,把此点作为字符大致的最高点
				top = i;

				//对i强行赋值以中断循环
				i=height;

				//跳出循环
				break;
			}

        //如果该点不是黑点,继续循环
		}
	}


    //从下往上扫描,找下边界

	//行
	for (i = height-1;i>=0;i--)
    {

		//列
		for (j=0;j<width;j++)
		{
			// 指向图像第i行,第j个象素的指针
			lpSrc = (unsigned char*)lpDIBBits + lLineBytes * i + j;

			//获取该点的灰度值
			gray = *(lpSrc);

			//判断是否为黑点
			if (gray == 0)
			{
				//若为黑点,把此点作为字符大致的最低点
				bottom = i;

				//对i强行赋值以中断循环
				i=-1;

				//跳出循环
				break;
			}

          //如果该点不是黑点,继续循环
		}
	
	}

	//lab 用作是否进入一个字符分割的标志
	bool lab = false;

	//表明扫描一列中是否发现黑色点
	bool black = false;

    //存放位置信息的结构体
	CRect rect;

	//计数器置零
	digicount=0;
   
	//行
	for (i=0;i<width;i++)
	{
		//开始扫描一列
		black=false;

		for (j=0;j<height;j++)
			{	
				// 指向图像第i行,第j个象素的指针
				lpSrc = (unsigned char*)lpDIBBits + lLineBytes * j + i;

				//获取该点的灰度值
				gray = *(lpSrc);

                //判断是否为黑点
				if (gray == 0)
				{
					//如果发现黑点,设置标志位
					black=true;

					//如果还没有进入一个字符的分割
					if(lab==false)
					{	
						//设置左侧边界
						rect.left = i;

						//字符分割开始
						lab = true;
					}

					//如果字符分割已经开始了
					else

                      //跳出循环
						break;
				}		
			}

		//如果已经扫到了最右边那列,说明整副图像扫描完毕。退出
           if(i==(width-1))
			   
		 //退出整个循环	   
		   break;

		//如果到此black仍为false,说明扫描了一列,都没有发现黑点。表明当前字符分割结束
		if(lab==true&&black==false)
		{   
           //将位置信息存入结构体中

           //设置右边界
			rect.right =i;

			//设置上边界
			rect.top =top;

			//设置下边界
			rect.bottom =bottom;

			//将框外括一个象素,以免压到字符
			rect.InflateRect (1,1);

            //将这个结构体插入存放位置信息的链表1的后面
			charRect1.push_back (rect);

			//设置标志位,开始下一次的字符分割
			lab=false;

			//字符个数统计计数器加1
			digicount++;
			
		}

		//进入下一列的扫描

	}

   //再将矩形轮廓矩形的top和bottom精确化

	//将链表1赋值给链表2
	charRect2=charRect1;

    //将链表2的内容清空
    charRect2.clear ();

	//建立一个新的存放位置信息的结构体
	CRect rectnew;

	//对于链表1从头至尾逐个进行扫描
	while(!charRect1.empty())
	{    
		//从链表1头上得到一个矩形
		rect= charRect1.front();

		//从链表1头上面删掉一个
		charRect1.pop_front();

		//计算更加精确的矩形区域

		//获得精确的左边界
		rectnew.left =rect.left-1 ;

		//获得精确的右边界
		rectnew.right =rect.right+1 ;

		//通过获得的精确左右边界对上下边境重新进行精确定位

		// 由下而上扫描计算上边界
		
		//行
		for(i=rect.top ;i<rect.bottom ;i++)
		{   
          //列
			for(j=rect.left ;j<rect.right ;j++)
			{   
                 // 指向图像第i行,第j个象素的指针
				lpSrc = (unsigned char*)lpDIBBits + lLineBytes * i + j;

				//如果这个象素是黑点
				if (*lpSrc == 0)
				{	
					//设置上边界
					rectnew.top = i-1;
					
					//对i进行强制定义以跳出循环
					i=rect.bottom  ;

					//跳出循环
					break;
				}	
			}
		}

		//由下而上扫描计算下边界
   
        //行
		for(i=rect.bottom-1 ;i>=rect.top  ;i--)
		{
			//列
			for(j=rect.left ;j<rect.right ;j++)
			{
				// 指向图像第i行,第j个象素的指针
				lpSrc = (unsigned char*)lpDIBBits + lLineBytes * i + j;

				//该点如果为黑点
				if (*lpSrc == 0)
				{	
					//设置下边界
					rectnew.bottom = i+1;

                    //对i进行强制定义以跳出循环
					i=-1;
                    //跳出循环
					break;
				}	
			}
		}

		//将得到的新的准确的位置信息从后面插到链表2的尾上
		charRect2.push_back (rectnew);
	}

	//将链表2 传递给链表1
	charRect1=charRect2;
	
	//解除锁定
	::GlobalUnlock(hDIB);

	//将链表1返回
	return charRect1;
}

⌨️ 快捷键说明

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