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

📄 bingxingbianjiedib.cpp

📁 VC++图像处理程序设计课本和代码.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			}
			//判断右面的点,如果为白,则压入堆栈
			//注意防止越界
			if(iCurrentPixelx < wide - 1)
			{
				lpSrc = (LPBYTE)temp + wide * iCurrentPixely + iCurrentPixelx + 1;
				//取得当前指针处的像素值,注意要转换为unsigned char型
				pixel =  *lpSrc;
				if (pixel == 255)
				{
					StackPoint++;
					Seeds[StackPoint].Height = iCurrentPixely;
					Seeds[StackPoint].Width = iCurrentPixelx + 1;
				}
			}
			//判断下面的点,如果为白,则压入堆栈
			//注意防止越界
			if(iCurrentPixely > 0)
			{
				lpSrc = (LPBYTE)temp + wide * (iCurrentPixely - 1) + iCurrentPixelx;
				//取得当前指针处的像素值,注意要转换为unsigned char型
				pixel =  *lpSrc;
				if (pixel == 255)
				{
					StackPoint++;
					Seeds[StackPoint].Height = iCurrentPixely - 1;
					Seeds[StackPoint].Width = iCurrentPixelx;
				}		 
			}
		}
		//释放堆栈
		delete Seeds;
	}
}

///***************************************************************/           
/*函数名称:Yuzhifenge(int Yuzhi)                                      
/*函数类型:void
/*参数说明:Yuzhi  ---阈值选取                                     
/*功能:对图像进行阈值分割。            
/***************************************************************/
void BingXingBianJieDib::Yuzhifenge(int Yuzhi)
{
	// 指向源图像的指针
	LPBYTE  p_data;
	LPBYTE	lpSrc;
	// 指向缓存图像的指针
	LPBYTE	lpDst;
	// 指向缓存DIB图像的指针
	LPBYTE	temp;
	//循环变量
	long i;
	long j;
	//图像的高和宽
	long wide;
	long height;
	p_data=GetData();
	if(m_pBitmapInfoHeader->biBitCount<9)	//灰度图像
		wide=GetWidth();
	else	//24位彩色
		wide=GetDibWidthBytes();
	height=GetHeight();
	temp=new BYTE[wide*height];
	memset(temp,255,wide*height);
	for (j=0;j<height;j++)
	{
		for(i=0;i<wide;i++)
		{
			lpSrc=p_data+wide*j+i;
			lpDst=temp+wide*j+i;
			if(abs(*lpSrc-Yuzhi)<30)
				*lpDst=Yuzhi;			
		}
	}
    memcpy(p_data,temp,wide*height);
	delete temp;	
}

///***************************************************************/           
/*函数名称:Qiyuzengzhang(CPoint point)                                      
/*函数类型:void
/*参数说明:point  ---获得生长点                                     
/*功能:对图像进行区域生长。            
/***************************************************************/
void BingXingBianJieDib::Qiyuzengzhang(CPoint point)
{
    // 循环变量
	int i;
	int j;
	// 指向DIB象素指针
	LPBYTE p_data;
	// 找到DIB图像象素起始位置	
    p_data=GetData();
	// DIB的宽度
	LONG wide = GetWidth();	
	// DIB的高度
	LONG height =GetHeight();
	if(m_pBitmapInfoHeader->biBitCount<9)	//灰度图像
	{
		// 计算种子点一的灰度值
		unsigned char  zhongzi=*(p_data+point.y*wide+point.x);	
		// 对各像素进行灰度转换
		for (j = 0; j < height; j ++)
		{
			for (i = 0; i < wide; i ++)
			{
				//获取各颜色分量
				unsigned char temp = *((unsigned char *)p_data + wide * j +i);
				if (abs(temp - zhongzi) < 10)    //当前点同种子一灰度值比较接近
				{								
					//将种子一的颜色赋给当前像素			 
					*((unsigned char *)p_data + wide * j + i ) = temp;
				}
				else 
					*((unsigned char *)p_data + wide * j + i ) =255;
			}
		}
	}
	else	//24位彩色
	{
		// 计算种子点一的灰度值
		int  zhongzi=*(p_data+(height-point.y)*wide*3+point.x*3);
		int   zhongzi2=*(p_data+(height-point.y)*wide*3+point.x*3+1);
		int   zhongzi3=*(p_data+(height-point.y)*wide*3+point.x*3+2);  	
		// 对各像素进行灰度转换
		for (j = 0; j < height; j ++)
		{
			for (i = 0; i < wide; i ++)
			{
				//获取各颜色分量
				int  temp = *((unsigned char *)p_data + 3*wide * j +i*3);
				int  temp2 = *((unsigned char *)p_data + 3*wide * j +i*3+1);
				int  temp3 = *((unsigned char *)p_data + 3*wide * j +i*3+2);
				if (abs(temp - zhongzi) < 10&&abs(temp2 - zhongzi2) < 10&&abs(temp3 - zhongzi3) < 10)    //当前点同种子一灰度值比较接近
				{								
					//将种子一的颜色赋给当前像素			 
					*(p_data + 3*wide * j + i*3 ) = temp;
					*(p_data +3*wide* j + i*3+1 ) = temp2;
					*(p_data +3*wide * j + i*3+2 ) = temp3;
				}
				else 
				{
					*(p_data + 3*wide * j + i*3 ) =255;
					*(p_data + 3*wide * j + i*3+1 ) =255;
					*(p_data + 3*wide * j + i*3+2 ) = 255;
				}
			}
		}
	} 
}
 
///***************************************************************/           
/*函数名称:Zhifangtu(float *fPs_Y)                              */
/*函数类型:void                                                 */
/*变量说明:tongji  灰度分布密度统计                             */                           
/*功能:对图像进行灰度直方图统计。								 */
/*****************************************************************/
void BingXingBianJieDib::Zhifangtu(float *tongji)
{
	// 循环变量
	int i;
	int j;
	// 灰度计数
	int huidu[256];
	int wide,height;    //原图长、宽
	// 变量初始化
	memset(huidu,0,sizeof(huidu));
	if(m_pBitmapInfoHeader->biBitCount<9)	//灰度图像
	{
        wide=this->GetWidth ();
        height=this->GetHeight ();
		int width= (((wide*24) + 31) / 32 * 4) ;
		LPBYTE temp1=new BYTE[wide*height+1024];    //新图像缓冲区
		//拷贝原图像到缓存图像
		memcpy( temp1,m_pData,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);
	}
	else	//24位彩色
	{
       	wide=this->GetDibWidthBytes();
        height=this->GetHeight ();
		LPBYTE  temp1=new BYTE[wide*height];    //新图像缓冲区
		//拷贝原图像到缓存图像
		memcpy(temp1,m_pData,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);
	} 
}

///***************************************************************/           
/*函数名称:BanYuZhi(int Yuzhi)                                      
/*函数类型:void
/*参数说明:Yuzhi  ---阈值选取                                     
/*功能:对图像进行半阈值分割。            
/***************************************************************/
void BingXingBianJieDib::BanYuZhi(int Yuzhi)
{
    // 指向源图像的指针
	LPBYTE  p_data;
	LPBYTE	lpSrc;
	// 指向缓存图像的指针
	LPBYTE	lpDst;
	// 指向缓存DIB图像的指针
	LPBYTE	temp;
	//循环变量
	long i;
	long j;
	//图像的高和宽
	long wide;
	long height;
	p_data=GetData();
	if(m_pBitmapInfoHeader->biBitCount<9)	//灰度图像
	{
		wide=GetWidth();
	}
	else	//24位彩色
		wide=GetDibWidthBytes();
	height=GetHeight();
	temp=new BYTE[wide*height];
	memset(temp,255,wide*height);
	for (j=0;j<height;j++)
	{
		for(i=0;i<wide;i++)
		{
			lpSrc=p_data+wide*j+i;
			
			lpDst=temp+wide*j+i;
			
			if((*lpSrc-Yuzhi)<30)
				*lpDst=*lpSrc;			
		}
	}
    memcpy(p_data,temp,wide*height);
	delete temp;
	
}

///***************************************************************/           
/*函数名称:Lunkuotiqu(CPoint SeedPoint)                                      
/*函数类型:void
/*参数说明:SeedPoint  ---种子点选取                                     
/*功能:对24位彩色图像进行轮廓提取。            
/***************************************************************/
void BingXingBianJieDib::Lunkuotiqu(CPoint SeedPoint)
{
    LPBYTE  p_data ;     //原图数据区指针
    int R,G,B,R1,G1,B1;
	int wide,height;    //原图长、宽
	// 指向源图像的指针
	LPBYTE	lpSrc;	
	// 指向缓存图像的指针
	LPBYTE	lpDst;	
	// 指向缓存DIB图像的指针
	LPBYTE	temp;	
	//循环变量
	int i;
	int j;
	p_data=GetData();
	wide=GetWidth();
    height=GetHeight();
	temp = new BYTE[wide * height*3];
	// 初始化新分配的内存,设定初始值为255
	memset(temp,  255, wide * height*3);
	lpSrc=p_data+wide*3*(height-SeedPoint.y)+3*SeedPoint.x;
	R1=*lpSrc;
    lpSrc++;
	G1=*lpSrc;
	lpSrc++;
	B1=*lpSrc;
	for(j=0;j<height;j++)
	{
		for(i=0;i<wide;i++)
		{
			lpSrc = (LPBYTE)p_data + wide * j*3 + i*3;
			// 指向目标图像倒数第j行,第i个象素的指针			
			lpDst = (LPBYTE)temp + wide * j*3 + i*3;
			int I;
			I=0;
			for(int k=i-1;k<i+2;k++)
			{
				for(int l=j-1;l<j+2;l++)
				{
					if(k>=0&&l>=0&&k<wide&&l<height)
					{
						R=*(p_data+l*wide*3+k*3);
						G=*(p_data+l*wide*3+k*3+1);
						B=*(p_data+l*wide*3+k*3+2);
						if(abs(R-R1)<10&&abs(G-G1)<10&&abs(B-B1)<10)
							I++;
					}
				}
			}
			if(I!=9)
			{	
				*lpDst=*lpSrc;
				*(lpDst+1)=*(lpSrc+1);
				*(lpDst+2)=*(lpSrc+2);
			} 
			else
			{
				*lpDst=255;
				*(lpDst+1)=255;
				*(lpDst+2)=255;
			}
		}
	}
	memcpy(p_data,temp, wide * height*3);
	delete temp;
}

/*************************************************************/
//此算法只适用于左边有边界的图像//
/*************************************************************/
void BingXingBianJieDib::Lunkuogenzong(CPoint SeedPoint)
{
	// 指向源图像的指针
	LPBYTE	lpSrc;
	LPBYTE   p_data ;
	int R1,G1,B1;
    int R,G,B;
	// 指向缓存图像的指针
	LPBYTE	lpDst;
	// 指向缓存DIB图像的指针
	LPBYTE	temp;
	int wide;
	int height; 
	//循环变量
	int i;
	int j;
	//像素值
    int pixel;
	//是否找到起始点及回到起始点
	bool bFindStartPoint;
	//是否扫描到一个边界点
	bool bFindPoint;
	//起始边界点与当前边界点
	Point StartPoint,CurrentPoint;
	//八个方向和起始扫描方向
	int Direction[8][2]={{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0}};
	int BeginDirect;
	p_data=GetData();
	wide=this->GetWidth();
	height=this->GetHeight();
	// 暂时分配内存,以保存新图像
	temp = new BYTE[wide*height*3];
	// 初始化新分配的内存,设定初始值为255
	lpDst = temp;
	memset(temp, (BYTE)255, wide * height*3);
	//先找到最左方的边界点
    lpSrc=p_data+wide*3*(height-SeedPoint.y)+3*SeedPoint.x;//确定鼠标点的色度值
	R1=*lpSrc;
    lpSrc++;
	G1=*lpSrc;
	lpSrc++;
	B1=*lpSrc;
	bFindStartPoint = false;
    int s= height-SeedPoint.y;
	for(i=SeedPoint.x;i>1;i--)  //从鼠标点开始向左寻找边界起始点
	{
		lpSrc = (LPBYTE)p_data + wide * (height-SeedPoint.y)*3 + i*3;
		// 指向目标图像倒数第j行,第i个象素的指针			
		lpDst = (LPBYTE)temp + wide * (height-SeedPoint.y)*3 + i*3;
		int count;
		count=0;
		for(int k=i-1;k<i+2;k++)
		{
			for(int l=s-1;l<s+2;l++)
			{
				if(k>=0&&l>=0&&k<wide&&l<height)
				{
					R=*(p_data+l*wide*3+k*3);
					G=*(p_data+l*wide*3+k*3+1);
					B=*(p_data+l*wide*3+k*3+2);
					if(abs(R-R1)<10&&abs(G-G1)<10&&abs(B-B1)<10)
						count++;
				}
			}
		}
		if(count!=9)
		{
			bFindStartPoint = true;
			StartPoint.Height = s;
			StartPoint.Width = i;
			// 指向目标图像倒数第j行,第i个象素的指针			
			lpDst = (LPBYTE)(temp + wide * s*3 + i*3);	
			*lpDst = 0;
			*(lpDst+1)=0;
			*(lpDst+2)=0;
			break;
		} 
	}	        
	//由于起始点是在左下方,故起始扫描沿左上方向
	BeginDirect = 0;
	//跟踪边界
	bFindStartPoint = false;
	//从初始点开始扫描
	CurrentPoint.Height = StartPoint.Height;
	CurrentPoint.Width = StartPoint.Width;
	while(!bFindStartPoint)
	{
		bFindPoint = false;
		while(!bFindPoint)
		{
			//沿扫描方向查看一个像素
			lpSrc = (LPBYTE)(p_data + 3*wide * ( CurrentPoint.Height + Direction[BeginDirect][1])
				+ 3*(CurrentPoint.Width + Direction[BeginDirect][0]));
			R =*lpSrc;
			G=*(lpSrc+1);
			B=*(lpSrc+2);
			if(abs(R-R1)<10&&abs(G-G1)<10&&abs(B-B1)<10)
			{
				bFindPoint = true;
				CurrentPoint.Height = CurrentPoint.Height + Direction[BeginDirect][1];
				CurrentPoint.Width = CurrentPoint.Width + Direction[BeginDirect][0];
				if(CurrentPoint.Height == StartPoint.Height && CurrentPoint.Width == StartPoint.Width)
				{
					bFindStartPoint = true;
				}
				lpDst =  (LPBYTE)(temp + 3*wide * CurrentPoint.Height + 3*CurrentPoint.Width);
				*lpDst = *lpSrc;
                *(lpDst+1) = *(lpSrc+1);
				*(lpDst+2) = *(lpSrc+2);
				//扫描的方向逆时针旋转两格
				BeginDirect--;
				if(BeginDirect == -1)
					BeginDirect = 7;
				BeginDirect--;
				if(BeginDirect == -1)
					BeginDirect = 7;
			}
			else
			{
				//扫描方向顺时针旋转一格
				BeginDirect++;
				if(BeginDirect == 8)
					BeginDirect = 0;
			}
		}
	}
	// 复制图像
	memcpy(p_data, temp, 3*wide * height);
	// 释放内存
    delete temp; 
}

⌨️ 快捷键说明

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