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

📄 dibimage.cpp

📁 神经网络代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	}
	
	// 计算灰度映射表
	for (i = 0; i < 256; i++)
	{
		lTemp = 0;		
		for (j = 0; j <= i ; j++)
		{
			lTemp += lCount[j];
		}
		
		// 计算对应的新灰度值
		bMap[i] = (BYTE) (lTemp * 255 / lHeight / lWidth);
	}
		
	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];
		}
	}
	
	return TRUE;
}


/*************************************************************************************
*函数名称:
* NewDIB()
*
* 参数:
* width			- 将要创建DIB的宽
* height			- 将要创建DIB的高
* biBitCount		- 将要创建DIB的位数。比如,如果要创建256色DIB,则此值为8
*
*返回值:
*  HDIB           - 成功返回DIB的句柄,否则返回NULL。
*
*说明:
*  该函数指定宽、高、颜色位数来创建一个新的DIB,并返回其句柄
*
*****************************************************************************************/

HDIB CDibImage::NewDIB(long width, long height, unsigned short biBitCount)
{
//计算新建的DIB每行所占的字节数
     long dwindth = (width*biBitCount/8+3)/4*4;

     //新建的DIB调色板中表项的数目 
	 WORD color_num;
     DWORD dwBitsSize;
     //通过输入的biBitCount值来确定调色板的表项数目 
	switch(biBitCount)
	{   

         //如果用1 bit来表示一个象素那么调色板中有两个表项 
		case 1:
         color_num=2;
		break;

         //如果用4 bit来表示一个象素那么调色板中有16个表项
		case 4:
		color_num=16;
		break;

         //如果用8bit来表示一个象素,那么调色板中得表项有256中(本程序大多采用这种形式)
		case 8:
		color_num=256;
		break;

          //其他的情况调色扳中没有表项,即真彩位图
		default:
		color_num=0;
		break;
	}

     //计算位图数据所占的空间
     //dwindth *height为象素数据所占的空间
     //40为位图信息头占的空间
     //color_num*4为调色板的表项所占的空间(调色板每个表项占4各个字节)

    dwBitsSize = dwindth *height + 40 + color_num*4;

     //建立指向位图文件的指针 
     LPSTR pDIB;

     //申请存储空间,并建立指向位图的句柄
     HDIB hDIB=(HDIB) ::GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, dwBitsSize);

     //如果申请空间不成功返回错误信息
	if (hDIB == 0)
	{
		return NULL;
	}

     //如果申请空间成功锁定内存,并将内存的指针传给pDIB
	pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
	
     //建立指向位图信息头结构的指针
	LPBITMAPINFO lpmf = (LPBITMAPINFO)pDIB;

     //给位图信息头内的各个参量赋值

     //指定位图信息头结构的大小为40字节
	lpmf->bmiHeader.biSize = 40;

     //指定新建位图的宽度
	lpmf->bmiHeader.biWidth = width;

    //指定新建位图的高度
     lpmf->bmiHeader.biHeight = height;

     //位平面数必须为1
     lpmf->bmiHeader.biPlanes = 1;

     //确定新建位图表示颜色是要用到的bit数
     lpmf->bmiHeader.biBitCount = biBitCount;

     //是否进行压缩
	lpmf->bmiHeader.biCompression = 0;

     //新建的位图中实际的位图数据所占的字节数
     lpmf->bmiHeader.biSizeImage = dwindth *height;

     //指定目标设备的水平分辨率
	lpmf->bmiHeader.biXPelsPerMeter = 2925;

     //指定目标设备的垂直分辨率
     lpmf->bmiHeader.biYPelsPerMeter = 2925;

     //新建图像实际用到的颜色数 如果为0则用到的颜色数为2的biBitCount次
     lpmf->bmiHeader.biClrUsed = 0;
 
     //指定新建图像中重要的颜色数,如果为0则所有的颜色都重要
	lpmf->bmiHeader.biClrImportant= 0; 	
    
     //如果新建的图像中含有调色板,则接下来对调色板的各种颜色分量赋初始值
	if(color_num!=0)
	{

		for(int i=0;i<color_num;i++)
		{
			lpmf->bmiColors[i].rgbRed =(BYTE)i;
			lpmf->bmiColors[i].rgbGreen =(BYTE)i;
			lpmf->bmiColors[i].rgbBlue =(BYTE)i;
		}
	}

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

     //返回新建位图的句柄
	 return hDIB;

}



void CDibImage::Convert256toGray(HDIB hDIB)
{
 
    LPSTR lpDIB;
	// 由DIB句柄得到DIB指针并锁定DIB
	lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)hDIB);

   LPSTR lpDIBBits;           //指向DIB的象素的指针
   LPSTR lpNewDIBBits;         //指向DIB灰度图图像(新图像)开始处象素的指针
  LONG lLineBytes;
   unsigned char * lpSrc;       //指向原图像象素点的指针
   unsigned char * lpdest;       //指向目标图像象素点的指针
   
  unsigned char *ired,*igreen,*iblue;
   
  long lWidth;             //图像宽度和高度
   long lHeight;
   
   long i,j;       //循环变量
   
   lWidth = DIBWidth(lpDIB);   //DIB 宽度
   lHeight = DIBHeight(lpDIB); //DIB 高度
   RGBQUAD *lpRGBquad;
   lpRGBquad = (RGBQUAD *)&lpDIB[sizeof(BITMAPINFOHEADER)]; //INFOHEADER后为调色板        
  if(DIBNumColors(lpDIB) == 256) //256色位图不作任何处理
   {
       return ;
  }
   
   if(DIBNumColors(lpDIB) != 256) //非256色位图将它灰度化
   {
       lLineBytes = WIDTHBYTES(lWidth*8*3);
       lpdest= new BYTE[lHeight*lWidth];
       lpDIBBits = (LPSTR)lpDIB + sizeof(BITMAPINFOHEADER);//指向DIB象素
       for(i = 0;i < lHeight; i++)
           for(j = 0;j < lWidth*3; j+=3)
           {
               ired   = (unsigned char*)lpDIBBits + lLineBytes * i + j + 2;
               igreen = (unsigned char*)lpDIBBits + lLineBytes * i + j + 1;
               iblue = (unsigned char*)lpDIBBits + lLineBytes * i +    j ;
               lpdest[i*lWidth + j/3] = (unsigned char)((*ired)*0.299 + (*igreen)*0.588 + (*iblue)*0.114);
           }
           
           //需要做三件事情:1、修改INFOHEADER 2、增加调色板 3、修改原图像灰度值
           LPBITMAPINFOHEADER lpBI;
           lpBI = (LPBITMAPINFOHEADER)lpDIB;
           lpBI->biBitCount = 8;
           
           //设置灰度调色板
           for(i = 0;i < 256;i++)
           {
               lpRGBquad[i].rgbRed   = (unsigned char)i;
               lpRGBquad[i].rgbGreen = (unsigned char)i;
               lpRGBquad[i].rgbBlue = (unsigned char)i;
               lpRGBquad[i].rgbReserved = 0;
           }
           
           lpNewDIBBits= FindDIBBits(lpDIB); //找到DIB图像象素起始位置
           lLineBytes=WIDTHBYTES(lWidth * 8);
           //修改灰度值
           for(i = 0;i < lHeight; i++)
               for(j = 0;j < lWidth; j++)
               {
                   lpSrc = (unsigned char*)lpNewDIBBits + lLineBytes * i+ j ;
                   *lpSrc=lpdest[i*lWidth+j];
               }
               delete lpdest;
   }    
   ::GlobalUnlock ((HGLOBAL)hDIB);
   

}

BOOL CDibImage::Bicolour(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
	unsigned char*	lpSrc;				// 指向源图像的指针	
//	LONG	lTemp;						// 临时变量	
	LONG	i;							// 循环变量
	LONG	j;	
//	BYTE	bMap[256];					// 灰度映射表	

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

	// 计算各个灰度值的计数
	for (i = 0; i < lHeight; i ++)
	{
		for (j = 0; j < lWidth; j ++)
		{
			lpSrc = (unsigned char *)lpDIBBits + lLineBytes * i + j;
			if(*lpSrc>220)*lpSrc=255; 
			  else *lpSrc=0;
		}
	}
	

	
	return TRUE;

}

BOOL CDibImage::DeleteScaterJudge(LPSTR 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;
        
  //传递灰度值
  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;

  //如果点在图像内、颜色为黑色并且没有被访问过

⌨️ 快捷键说明

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