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

📄 imageprocess.cpp

📁 医学图象处理系统
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//***********************************************************
BOOL Image_Binary_Erosion(BYTE *image,int ImgW,int ImgH,BYTE *Mask,int MaskSize,BYTE TargetGray)
{
	int	 Imagesize=ImgW*ImgH;
	if (image==NULL || Imagesize==0) return FALSE;

	BYTE *tmpImage = new BYTE[Imagesize],    *tm;
	BYTE **S_RowAddress = new BYTE*[ImgH];
	BYTE **D_RowAddress = new BYTE*[ImgH];
	int i, j, i1, j1, MaskR= MaskSize/2;
	BOOL KillIt;
	S_RowAddress[0] = image;
	D_RowAddress[0] = tmpImage;
	for(i=1 ; i<ImgH ;i++)
	{
		D_RowAddress[i] = D_RowAddress[i-1] + ImgW;
		S_RowAddress[i] = S_RowAddress[i-1] + ImgW;
	}
	memset(tmpImage, ~TargetGray, Imagesize);

    for(j=MaskR; j<ImgH-MaskR; j++)
	{
		for(i=MaskR; i<ImgW-MaskR; i++)
		{        	
			if(S_RowAddress[j][i]==TargetGray) 
			{
				tm = Mask;
				KillIt = FALSE;
				for(j1=-MaskR; j1<=MaskR; j1++)
				{
					for(i1=-MaskR; i1<=MaskR; i1++)
					{
						if(*tm++)
						{
							if(S_RowAddress[j+j1][i+i1]!=TargetGray) 
							{
								KillIt=TRUE;
								j1 = i1 = MaskR + 1;
							}
						}
					}
				}
				if(KillIt) D_RowAddress[j][i] =~TargetGray;
				else  D_RowAddress[j][i] = TargetGray;
			}			
		}
	}
	memcpy(image, tmpImage, Imagesize);
	if(  tmpImage!=NULL)    delete []tmpImage;
	if(S_RowAddress!=NULL)  delete []S_RowAddress;
	if(D_RowAddress!=NULL)  delete []D_RowAddress;
	return TRUE;
}
//***********************************************************
//函数类别: 二值图像的处理
//函数名称:                       
//           Binary_Dilation
//函数用途:
//           进行二值图Binary_Dilation膨胀运算
//
//参数说明:
//调用函数:
//           
//被调函数: 
//           some function , at all,  I don't know 
//原始作者: 陆宏伟
//原始日期: 21/4/1999 
//***********************************************************
BOOL Image_Binary_Dilation(BYTE *image,int ImgW,int ImgH,BYTE *Mask,int MaskSize,BYTE TargetGray)
{
	int	 Imagesize=ImgW*ImgH;
	if (image==NULL || Imagesize==0) return FALSE;

	BYTE *tmpImage = new BYTE[Imagesize],    *tm;
	BYTE **S_RowAddress = new BYTE*[ImgH];
	BYTE **D_RowAddress = new BYTE*[ImgH];
	int i, j, i1, j1, MaskR= MaskSize/2;

	S_RowAddress[0] = image;
	D_RowAddress[0] = tmpImage;
	for(i=1 ; i<ImgH ;i++)
	{
		D_RowAddress[i] = D_RowAddress[i-1] + ImgW;
		S_RowAddress[i] = S_RowAddress[i-1] + ImgW;
	}
	memset(tmpImage, ~TargetGray, Imagesize);

    for(j=MaskR; j<ImgH-MaskR; j++)
	{
		for(i=MaskR; i<ImgW-MaskR; i++)
		{        	
			if(S_RowAddress[j][i]==TargetGray) 
			{
				tm = Mask;
				for(j1=-MaskR; j1<=MaskR; j1++)
				{
					for(i1=-MaskR; i1<=MaskR; i1++)
					{
						if(*tm++)
						{
							D_RowAddress[j+j1][i+i1] = TargetGray; 
						}
					}
				}
			}			
		}
	}
	memcpy(image, tmpImage, Imagesize);
	if(  tmpImage!=NULL)    delete []tmpImage;
	if(S_RowAddress!=NULL)  delete []S_RowAddress;
	if(D_RowAddress!=NULL)  delete []D_RowAddress;
	return TRUE;
}
//***********************************************************
//函数类别: 二值图像的处理
//函数名称:                       
//           Binary_grass_label
//函数用途:
//           二值图中的区域的标记函数;
//
//原始作者: 陆  宏  伟
//原始日期: 21/1 /1999
//修改日期:  25/6 /1999  以后再也不会发生堆栈溢出的情况了, Ha Ha Ha!!!
//***********************************************************
int px =0 , py = 0;
int Image_Binary_grass_label(BYTE *image,    // 数据的指针
							 int imgW ,      // 数据的宽度(列数)
							 int imgH,       // 数据的高度(行数)
							 BYTE TargetGray)// 目标的灰度值(是白目标还是黑目标)
{
	int i, j, k, l;  // 常用循环变量 
	int Nowx, Nowy;  // 当前的图像坐标位置
	int PixelNum;    // 记录递归的次数
	int Neighbor;    // 邻域点的个数
	int AreaLabel= 1;// 标记的值
	
    BYTE **S_RowAddress = new BYTE*[imgH]; //定义指向图像数据每行行首的地址,用来加快运算速度
	BYTE GLabel;    // 记录邻域中像素点的标记值
	
	//给指向图像数据每行行首的地址赋值
	S_RowAddress[0] = image;
	for(i=1 ; i<imgH ;i++)
	{
		S_RowAddress[i] = S_RowAddress[i-1] + imgW;
	}

    BOOL GrassOk     = false; //定义递归调用是否成功的标志位

	for(i=0; i<imgW; i++)
	{
		for(j=0; j<imgH; j++)
		{
			// 如果是目标点,则继续,否则进行下一次循环
			if(S_RowAddress[j][i] != TargetGray) continue;

			//判断当前点邻域内是否有标记过的点
			Neighbor = PixelNum = 0;
			for(k=-1; k<=1; k++)
			{
				for(l=-1; l<=1;  l++)
				{
					Nowx = i + k;
					Nowy = j + l;
					//防止指针越界
					if( Nowx >= 0 && Nowx < imgW && 
						Nowy >= 0 && Nowy < imgH && 
						S_RowAddress[Nowy][Nowx] > 0 && 
						S_RowAddress[Nowy][Nowx] < 255 )
					{
						// 如果该点的邻域有标记过的点,
						// 则Neighbor加1,并将该标记值
						// 记录在变量GLabel
 						GLabel = S_RowAddress[Nowy][Nowx];
						Neighbor++;
					}
				}
			}//*/
			
			// 如果该点的邻域有标记过的点, 
			// 则仍然用该标记值从当前点开始进行标记
			// 否则使用新的标记值
			if(Neighbor)
			{
				GrassOk = Image_Binary_grass( S_RowAddress, imgW, imgH, 
					      TargetGray, i, j, GLabel, PixelNum);
				AreaLabel--;
			}
			else//*/
			{	
				px = i, py = j;
				do 
				{
					Neighbor = PixelNum = 0;
					for(k=-1; k<=1; k++)
					{
						for(l=-1; l<=1;  l++)
						{
							Nowx = px + k;
							Nowy = py + l;
							//防止指针越界
							if( Nowx >= 0 && Nowx < imgW && 
								Nowy >= 0 && Nowy < imgH && 
								S_RowAddress[Nowy][Nowx] > 0 && 
								S_RowAddress[Nowy][Nowx] < 255 )
							{
								// 如果该点的邻域有标记过的点,
								// 则Neighbor加1,并将该标记值
								// 记录在变量GLabel
 								GLabel = S_RowAddress[Nowy][Nowx];
								Neighbor++;
							}
						}
					}//*/
					if( Neighbor )
						GrassOk = Image_Binary_grass( S_RowAddress, imgW, imgH, 
								  TargetGray, px, py, GLabel, PixelNum);
					else
						GrassOk = Image_Binary_grass( S_RowAddress, imgW, imgH, 
								  TargetGray, px, py, AreaLabel, PixelNum);

					//如果标记成功,则标记值加1
				} while( !GrassOk );
				//if(GrassOk) 
				if( GrassOk )
					AreaLabel++;
			}

			// 如果标记的区域大于253个,返回
			if(AreaLabel >= 255) 
			{
				if(S_RowAddress!=NULL) delete []S_RowAddress;
				return 254;
			}
		}
	}    
	// 收回分配的内存
	if(S_RowAddress!=NULL)  delete []S_RowAddress;
	// 返回标记的区域的数目
	return AreaLabel == 1  ?  GrassOk : AreaLabel - 1;
}
//***********************************************************
//函数类别: 二值图像的处理
//函数名称:                       
//           Binary_grass
//函数用途:
//           二值图中的区域的标记函数
//           (采用递归形式)
//
//原始作者: 陆  宏  伟
//原始日期: 21/1 /1999
//修改日期:  25/6 /1999  以后再也不会发生堆栈溢出的情况了, Ha Ha Ha!!!
//***********************************************************
BOOL Image_Binary_grass(BYTE **image,   // 数据的指针
						int imgW ,      // 数据的宽度(列数)
						int imgH,       // 数据的高度(行数)
						BYTE TargetGray,// 目标的灰度值(是白目标还是黑目标)
				        int Startx,    // 起始点的x坐标
						int Starty,    // 起始点的y坐标
						int AreaLabel,  // 区域的标记值
						int &PixelNum)  // 当前区域已标记过的点数目
{
	int i, j;        // 常用循环变量 
	int Nowx, Nowy;  // 当前的图像坐标位置

	PixelNum ++;     // 递归的次数加1
	if(PixelNum==6000) 
	{
		px = Startx;
		py = Starty;
		return false;
	}
	else if(PixelNum>6000)  return false; 
	

	image[Starty][Startx] = AreaLabel;// 将当前像素点标记

	for(i=-1; i<=1; i++)
	{
		for(j=-1; j<=1;  j++)
		{
			Nowx = Startx + i;
			Nowy = Starty + j;
			if( Nowx >= 0 && Nowx < imgW && 
				Nowy >= 0 && Nowy < imgH && 
				image[Nowy][Nowx] == TargetGray )
			{
				Image_Binary_grass(image, imgW, imgH, TargetGray, 
					               Nowx,  Nowy, AreaLabel, PixelNum);
			}
		}
	}
	return  (PixelNum>6000) ?  false : true;
}

void Image_Binary_Get_Area_Attrib(BYTE *image, int imgW, int imgH, struct AreaAttrib *attrib, int PtNum)
{
	int     i,j ,ImageSize=imgW*imgH;
	int	    *minx = new int[PtNum];
	int     *maxx = new int[PtNum];
    int     *miny = new int[PtNum];
	int     *maxy = new int[PtNum];
	int	    *Sumx = new int[PtNum];
	int     *Sumy = new int[PtNum];
    int     *Area = new int[PtNum];
	memset(maxx,0,sizeof(int)*PtNum);
	memset(maxy,0,sizeof(int)*PtNum);
    memset(Sumx,0,sizeof(int)*PtNum);
	memset(Sumy,0,sizeof(int)*PtNum);
	memset(Area,0,sizeof(int)*PtNum);
	for(i=0;i<PtNum;i++)
	{
		minx[i] = ImageSize;
		miny[i] = ImageSize;
	}
    for(j=0; j<imgH; j++)
	{
		BYTE   *temp = image + j*imgW;
		for(i=0; i<imgW; i++)
		{
			BYTE gray = temp[i];
			if(gray>0&&gray<=PtNum)
			{
				gray--;
				Sumx[gray]+=i;
				Sumy[gray]+=j;
                Area[gray]++;
				if(i<minx[gray]) minx[gray] = i;
				if(i>maxx[gray]) maxx[gray] = i;

				if(j<miny[gray]) miny[gray] = j;
				if(j>maxy[gray]) maxy[gray] = j;
			}
		}
	}
    for(i=0;i<PtNum;i++)
	{
		attrib[i].Centerx        = (double)Sumx[i]/(double)Area[i];
		attrib[i].Centery        = (double)Sumy[i]/(double)Area[i];
		attrib[i].Outline.top    = miny[i];
		attrib[i].Outline.left   = minx[i];
		attrib[i].Outline.bottom = maxy[i];
		attrib[i].Outline.right  = maxx[i];
		attrib[i].Area           = (double)Area[i];		
	}
	if(Sumx!=NULL) delete []Sumx;
	if(Sumy!=NULL) delete []Sumy;
	if(Area!=NULL) delete []Area;
	if(minx!=NULL) delete []minx;
	if(maxx!=NULL) delete []maxx;
	if(miny!=NULL) delete []miny;
	if(maxy!=NULL) delete []maxy;
}

void Image_Edge_RotateInvariantOperator(BYTE *InputImage, int ImgW, int ImgH, int Masksize)
{
	int	 Imagesize=ImgW*ImgH;
	if (InputImage==NULL || Imagesize==0) return ;
	int  i,j;
	int  Area = Masksize*Masksize; 
	int  HalfArea = Area/2;
	int	 r=Masksize/2; 
	BYTE *tmpImage = new BYTE[Imagesize];
    BYTE **RowAddress = new BYTE*[ImgH];
	//initialize 
	double *Operatorx = new double[Area];
	double *Operatory = new double[Area];
	memset(tmpImage, 0, Imagesize);
	memset(Operatorx, 0, Area*sizeof(double));
	memset(Operatory, 0, Area*sizeof(double));

	double *tmpOpx = Operatorx , *tmpOpy = Operatory;
	double Coef1 = PI/double(r+1), Mr;
	int    dx, dy, R02=r*r, Radius, nG;
	for(dy=-r; dy<=r; dy++)
	{
		for(dx=-r; dx<=r; dx++)
		{
			Radius = dx*dx +dy*dy;
			if(Radius<=R02)
			{
				Mr = sqrt(Radius);
				*tmpOpx = cos(2*Mr*Coef1)*sin(dx*Coef1);
				*tmpOpy = cos(2*Mr*Coef1)*sin(dy*Coef1);
			}
			tmpOpx++;
			tmpOpy++;
		}
	}

	RowAddress[0] = InputImage;
	for(i=1 ; i<ImgH ;i++)
	{
		RowAddress[i] = RowAddress[i-1] + ImgW;
	}

	CProgressDlg * MsgHandler = new CProgressDlg();
    MsgHandler->Create(NULL);
    MsgHandler->SetStatus("旋转不变量算子检测边缘处理");

	double gx, gy;
	BYTE *Image = tmpImage + r*ImgW;
	for(j=r; j<ImgH-r; j++)
	{		
		for(i=r; i<ImgW-r; i++)
		{
			gx = gy = 0;
			tmpOpx = Operatorx;
			tmpOpy = Operatory;
			for(dy=-r; dy<=r; dy++)
			{
				for(dx=-r; dx<=r; dx++)
				{
					gx += (*tmpOpx++)* RowAddress[j+dy][i+dx];
					gy += (*tmpOpy++)* RowAddress[j+dy][i+dx];
				}
			}
			nG  = int(sqrt(gx*gx+gy*gy) + 0.5);
			Image[i] = (nG>255) ? 255: nG;		
		}
		Image += ImgW;
		MsgHandler->SetPos(100 * j /ImgH );
	}
	memcpy(InputImage,tmpImage,Imagesize);

	if(tmpImage!=NULL)  delete []tmpImage;
	if(RowAddress!=NULL)  delete []RowAddress;
	if(Operatorx!=NULL)  delete []Operatorx;
	if(Operatory!=NULL)  delete []Operatory;
	MsgHandler->DestroyWindow();
    delete  MsgHandler;
}
//***********************************************************
//函数类别: 图像分割
//函数名称:                       
//           Image_EdgeOrention_RotateInvariantOperator
//函数用途:
//           用来进行图像边缘方向角度的计算,各个方向的角度表示
//           类似于各种图像处理书籍中的介绍。
//
//参数说明:
//           BYTE  * InputImage        数据的指针
//           int     ImgW          数据的宽度(行数)
//           int     ImgH          数据的高度(列数)      
//             
//原始作者: 陆宏伟
//原始日期: 25/5/1999 
//***********************************************************
void Image_EdgeOrention_RotateInvariantOperator(BYTE *InputImage, int ImgW, int ImgH, int Masksize)
{
	int	 Imagesize=ImgW*ImgH;
	if (InputImage==NULL || Imagesize==0) return ;

	int  i,j;
	int  Area = Masksize*Masksize; 
	int  HalfArea = Area/2;
	int	 r=Masksize/2; 
	BYTE *Image1, *Image2;
	BYTE *MagntiudeImage = new BYTE[Imagesize];
	BYTE *OrientationImage = new BYTE[Imagesize];
    BYTE **RowAddress = new BYTE*[ImgH];
  	//initialize 
	memset(MagntiudeImage,   0, Imagesize);
	memset(OrientationImage, 0, Imagesize);

	//initialize 
	double *Operatorx = new double[Area];
	double *Operatory = new double[Area];
	memset(Operatorx, 0, Area*sizeof(double));
	memset(Operatory, 0, Area*sizeof(double));

	double *tmpOpx = Op

⌨️ 快捷键说明

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