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

📄 dibimage.cpp

📁 种子填充算法用来在封闭曲线形成的环中填充某中颜色
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	// 循环控制变量
	int k ;
	// 图象的横纵坐标,用来对当前象素的4邻域进行遍历
	
	while (Start<=End)
	{
		// 当前种子点的坐标
		Current.x = GrowX[Start];
		Current.y = GrowY[Start];
		// 对当前点的4邻域进行遍历
		for (k=0; k<4; k++)	
		{	
			// 4邻域象素的坐标
			xx = Current.x+Dx[k];
			yy = Current.y+Dy[k];
			
			// 判断象素(xx,yy) 是否在图像内部
			// 判断象素(xx,yy) 是否已经处理过
			// *lpDst==255 表示还没有处理
			// 指向源图像(xx,yy)象素的指针			
			lpSrc = (unsigned char *)lpDIBBits + lWidth * (lHeight-yy) + xx;
			lpSrc1 = (unsigned char *)lpDIBBits + lWidth * (lHeight-Current.y) + Current.x;
			// 指向目标图像第j行,第i个象素的指针			
			lpDst = (unsigned char *)lpImage + lWidth * (lHeight-yy) + xx;
			// 生长条件:判断象素(xx,yy)和当前象素(nCurrX,nCurrY) 象素值差的绝对值
			if ((xx < lWidth) && (xx>=0) && (yy<lHeight) && (yy>=0) && (*lpDst==255) 
					&& abs(*lpSrc-*lpSrc1)<Dib_yuzhi )
			{
				// 堆栈的尾部指针后移一位
				End++;
				// 象素(xx,yy) 压入栈
				GrowX[End] = xx;
				GrowY[End] = yy;
				// 目标图像为黑点,同时也表明该象素处理过
				*lpDst=0 ;
			}
		}
		Start++;
	}
	// 复制区域生长后的图像
	memcpy(lpDIBBits, lpImage, lWidth * lHeight);
	// 释放内存
	delete[] lpImage;
	delete[] GrowX;
	delete[] GrowY;
	// 返回
//	return TRUE;
}
/*************************************************************************
 * 函数名称:
 *   TongJi() --统计灰度分布密度
 * 参数:
 *   LPSTR lpDIB        - 指向DIB对象的指针
 *   float *tongji      - 指向灰度分布密度的指针
 * 返回值:
 *       无
 * 说明:
 *    该函数用来统计图象中的灰度分布密度
 *************************************************************************/

void CDibImage::TongJi(LPSTR lpDIB,float *tongji)
{   // 循环变量
	int i;
	int j;
	// 灰度计数
	int huidu[256];
	int wide,height;    //原图长、宽
	// 变量初始化
	    memset(huidu,0,sizeof(huidu));
        wide=DIBWidth(lpDIB);
        height=DIBHeight(lpDIB);
		LPBYTE temp1=new BYTE[wide*height+1024];        //新图像缓冲区    
		memcpy( temp1,FindDIBBits(lpDIB),wide*height ); //拷贝原图像到缓存图像
		// 对各像素进行灰度统计
		for (i = 0; i < height; i ++)
		{
			for (j = 0; j <wide; j ++)
			{
				unsigned char  temp =  temp1[wide* i + j] ;			  			 
				// 灰度统计计数
				huidu[temp]++;		
			}
		}
		// 计算灰度分布密度
		for(i=0;i<256;i++)
			tongji[i] = huidu[i] / (height * wide *1.0f);	
}
 /*************************************************************************
 * 函数名称:
 *  MuBiaoErZhiHua() --目标选择法阈值分割
 * 参数:
 *   LPSTR lpDIBBits    - 指向源DIB图像指针
 *   LPSTR lpDIB        - 指向DIB对象的指针
 *   LONG  lWidth       - 源图像宽度(象素数)
 *   LONG  lHeight      - 源图像高度(象素数)
 *    int  xx           - 种子点的横坐标
 *    int  yy           - 种子点的纵坐标
 * 返回值:
 *       无
 * 说明:
 *    将图象中的像素点与种子点的像素值差值比较,小于标准差的归0,大于标准差的归255
 *************************************************************************/

void CDibImage::MuBiaoErZhiHua(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int xx, int yy)
{
 unsigned char*	lpSrc;	  // 指向DIB第i行,第j个象素的指针
    int	ZhongZi;	      // 记录种子点的像素值
    LONG	i;	          // 循环变量
	LONG	j;	
	LONG	lLineBytes;	  // 图像每行的字节数
		
	lLineBytes = WIDTHBYTES(lWidth * 8);// 计算图像每行的字节数	
	ZhongZi=*((unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - yy) + xx);
	BYTE* p_temp=new BYTE[lWidth*lHeight];// 申请并分配中间缓存
    memcpy(p_temp,lpDIBBits,lWidth*lHeight);// 复制图象数据到中间缓存	
	for(i = 0; i < lHeight; i++)		// 每行
	{		
		for(j = 0; j < lWidth; j++)		// 每列
		{
			// 指向DIB第i行,第j个象素的指针
			lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;			
	
			if (abs((*lpSrc)-ZhongZi)<30)		// 判断是否小于标准差10
			{
			   *(p_temp + lLineBytes * (lHeight - 1 - i) + j)=0;     
			}
			else
			{
			   *(p_temp + lLineBytes * (lHeight - 1 - i) + j)=255; 
			}
		}
	}
   	memcpy(lpDIBBits,p_temp,lWidth*lHeight); // 复制中间缓存到图象数据	
	delete p_temp;
}
/*****************************************************
* 
*   函数名称:
*      Template:
*
*    参数:
*	   HDIB    hDIB         -图像的句柄
*      int  tem_w           -模板的宽度
*      int  tem_h           -模板的高度
*      
*    功能:
*	   对图像进行中值
*
*    说明:
*	   为处理方便起见,模板的宽度和高度都应为奇数
*******************************************************/

HDIB CDibImage::MidFilter(HDIB hDIB,int tem_w,int tem_h)
{
 //统计中间值
    double mid;

	BYTE *temp=(BYTE*)malloc(tem_w*tem_h*sizeof(BYTE));

    //指向图像起始位置的指针
    BYTE *lpDIB=(BYTE*)GlobalLock((HGLOBAL) hDIB);

	//指向象素起始位置的指针
	BYTE *pScrBuff =(BYTE*)FindDIBBits((char*)lpDIB);
   
	//获取图像的颜色信息
    int numColors=(int)DIBNumColors((char *)lpDIB);

    //如果图像不是256色返回
     if (numColors!=256) 
	 {   
        //解除锁定
	GlobalUnlock((HGLOBAL) hDIB);

		//返回
		return(hDIB);
	 }
    
    //将指向图像象素起始位置的指针,赋值给指针变量
    BYTE* oldbuf = pScrBuff;

    //循环变量
    int i,j,m,n;

	int w, h, dw;

	//获取图像的宽度
	w = (int) DIBWidth((char *)lpDIB);
	
	//获取图像的高度
	h = (int) DIBHeight((char *)lpDIB);
	
	//计算图像每行的字节数
	dw = (w+3)/4*4;      
	
	//建立一个和原图像大小相同的25色灰度位图
    HDIB newhDIB=NewDIB(w,h,8);  
    
	//指向新的位图的指针
	BYTE *newlpDIB=(BYTE*)GlobalLock((HGLOBAL) newhDIB);

	//指向新的位图的象素起始位置的指针 
    BYTE *destBuf = (BYTE*)FindDIBBits((char *)newlpDIB);
    
   //将指向新图像象素起始位置的指针,赋值给指针变量
    BYTE *newbuf=destBuf; 
	
	//对图像进行扫描
   
	//行 
    for(i=0;i<h;i++)
    {  
		//列
	   for(j=0;j<w;j++)
	   {   

		   //为统计变量赋初始值
	       

         //对于图像的4个边框的象素保持原灰度不变
	     if( j<((tem_w-1)/2) || j>(w-(tem_w+1)/2) || i<((tem_h-1)/2) || i>(h-(tem_h+1)/2) )
	      *(newbuf+i*dw+j)=*(oldbuf+i*dw+j);
		 
         //对于其他的象素进行模板操作
		 else 
         { 

          //将点(i,j)点作为模板的中心
          for(m=i-((tem_h-1)/2);m<=i+((tem_h-1)/2);m++)
          {
		     for(n=j-((tem_w-1)/2);n<=j+((tem_w-1)/2);n++)
		    
             //将以点(i,j)为中心,与模板大小相同的范围内的象素传递到模板矩阵中
		     temp[(m-i+((tem_h-1)/2))*tem_w+n-j+((tem_w-1)/2)]=*(oldbuf+m*dw+n);
		  
		  }
          
		 //利用气泡法计算中值
           for(m=0;m<tem_w*tem_h-1;m++)
           {
		   
		      for(n=0;n<tem_w*tem_h-m-1;n++)
			  {
			    if(temp[n]>temp[n+1]) 
			    mid=temp[n];
                temp[n]=temp[n+1];
			    temp[n+1]=mid;
			  }
		   
		   } 

           //将计算的结果放到新的位图的相应位置
	      *(newbuf+i*dw+j)=temp[(tem_w*tem_h-1)/2];
		 }
	   }
	} 
   
	//解除锁定
	::GlobalUnlock((HGLOBAL)hDIB);
    
	//返回新的位图的句柄
    return(newhDIB);
}

HDIB CDibImage::NewDIB(long width, long height, unsigned short biBitCount)
{
long dwindth = (width*biBitCount/8+3)/4*4; // align 4 bytes
	WORD color_num;
	switch(biBitCount)
	{
		case 1:
			color_num=2;
			break;

		case 4:
			color_num=16;
			break;
		case 8:
			color_num=256;
			break;
		default:
			color_num=0;
			break;
	}

	long dwBitsSize = dwindth *height + 40 + color_num*4;// 40 LPBIMHEAD

	LPSTR pDIB;
	HDIB hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
	if (hDIB == 0)
	{
		return NULL;
	}
	pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
	
	LPBITMAPINFO lpmf = (LPBITMAPINFO)pDIB;
	lpmf->bmiHeader.biSize = 40;//40
	lpmf->bmiHeader.biWidth = width; //i_info.width;
    lpmf->bmiHeader.biHeight = height;
    lpmf->bmiHeader.biPlanes = 1;
	lpmf->bmiHeader.biBitCount = biBitCount;// 24
	lpmf->bmiHeader.biCompression = 0;
    lpmf->bmiHeader.biSizeImage = dwindth *height;
	lpmf->bmiHeader.biXPelsPerMeter = 2925;
    lpmf->bmiHeader.biYPelsPerMeter = 2925;
    lpmf->bmiHeader.biClrUsed = 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;
}

⌨️ 快捷键说明

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