improc.cpp

来自「图像处理软件,功能比较基础」· C++ 代码 · 共 2,011 行 · 第 1/4 页

CPP
2,011
字号
/*模板上、下、左、右坐标    模板数据从(0,0)至(th-1,tw-1),tx1,tx2,ty1,ty2用来确定搜索区域*/
	int tx0,ty0;   /*模板中心位置*/
	int th,tw;     /*模板尺寸*/
	int t;         /*模板面积*/

	int newtx1,newty1;  /*新模板左上坐标*/

	float Tc=0.5;       /*相关门限*/
    float To=0.8;   	/*交迭门限*/


/*模板和区域的交迭面积、和模板交迭的区域面积*/
	int *o;
	int *r;
    
    imageHeight = Row;
    imageWidth  = Col;
    orgImage2 = OrigImg;
    orgImage1 = Template;

    sx1=0;
    sx2=Row-1;
    sy1=0;
    sy2=Col-1;

    tx1 = *tr1;
    tx2 = *tr2;
    ty1 = *tc1;
    ty2 = *tc2;
//	unsigned char **orgImage1;  /*存放从[0,0]开始的模板数据*/

/*读取模板、待匹配图像原始图像数据*/
//    unsigned char **temp=m_OrgImage->GetImagePointer();
//    unsigned char **orgImage2=m_SecImage->GetImagePointer();

/*取图像的宽(列)、长(行)*/
//	imageWidth=m_SecImage->GetImageCol();
//    imageHeight=m_SecImage->GetImageRow();

/*分配内存*/
	c=(float**)fspace_2d(imageHeight,imageWidth,sizeof(float));
//	orgImage1=(unsigned char**)fspace_2d(imageHeight,imageWidth,sizeof(unsigned char));
    project=(int*)malloc(grayLevel*sizeof(int));
    o=(int*)malloc(grayLevel*sizeof(int));
    r=(int*)malloc(grayLevel*sizeof(int));


	th=tx2-tx1+1;
	tw=ty2-ty1+1;

	tx0=(tx1+tx2)/2;     /*简单的中心位置*/
	ty0=(ty1+ty2)/2;

//	sx1=tx0-th*2/3;    /*搜索区域*/
//	sx2=tx0+th*2/3;
//	sy1=ty0-tw*2/3;
//	sy2=ty0+tw*2/3;

/*判别搜索区域是否超出图像范围*/
//	if(sx1<0)
//		sx1=0;
//	if(sx2>=imageHeight)
//		sx2=imageHeight-1;
//	if(sy1<0)
//		sy1=0;
//	if(sy2>=imageWidth)
//		sy2=imageWidth-1;

	newTemplate = (unsigned char**)fspace_2d(sx2-sx1+1,sy2-sy1+1,sizeof(unsigned char));
    if(!newTemplate) return;

/*将模板数据放入orgImage1中*/
//	for(i=0;i<th;i++)
//		for(j=0;j<tw;j++)
//			orgImage1[i][j]=temp[i+tx1][j+ty1];

/*计算模板面积*/
    t=0;
	for(m=0;m<th;m++)
		for(n=0;n<tw;n++)
		{
			if(orgImage1[m][n]==255)
			    t++;
		}



/*计算相关值*/
	for(i=sx1;i<sx2-th;i++)
		for(j=sy1;j<sy2-tw;j++)
			c[i][j]=0.0;
    
	for(i=sx1;i<sx2-th;i++)
		for(j=sy1;j<sy2-tw;j++)
		{
            k=0;
        	for(l=0;l<grayLevel;l++)
        		project[l]=255;

		/*寻找投影区域*/
			for(m=0;m<th;m++)
				for(n=0;n<tw;n++)
				{
					if(orgImage1[m][n]==255)
					{
						a=0;    /*a=0表示新区域*/
						for(l=0;l<=k;l++)    /*判别是否为新区域*/
						{
							if(orgImage2[i+m][j+n]==(unsigned char)project[l])
							{
							    a=1;
								break;
							}
						}
						if(a==0)
						{
							project[k]=orgImage2[i+m][j+n];
							k++;
						}
					}
				}


		    for(l=0;l<k;l++)
			{
				o[l]=0;
				r[l]=0;
			}

		/*计算模板和区域的交迭面积、(和模板有交迭的)区域的面积*/
			for(l=0;l<k;l++)
			{
            	for(m=i;m<i+th;m++)
            		for(n=j;n<j+tw;n++)
					{
						if((orgImage1[m-i][n-j]==255)&&(orgImage2[m][n]==project[l]))
							o[l]++;
					}
            	for(m=sx1;m<sx2;m++)
            		for(n=sy1;n<sy2;n++)
					{
						if(orgImage2[m][n]==project[l])
							r[l]++;
					}
			}

		/*计算相关值*/
			for(l=0;l<k;l++)
				c[i][j]=c[i][j]+(float)(o[l]*o[l])/(float)r[l];

			c[i][j]=c[i][j]/(float)t;

		}

/*寻找最大相关值*/
	max=0.0;
	for(i=sx1;i<sx2-th;i++)
		for(j=sy1;j<sy2-tw;j++)
		{
			if(c[i][j]>max)
			{
				newtx1=i;
				newty1=j;
				max=c[i][j];
			}
		}

/*判断最大相关值是否大于相关门限*/
/*是则更新模板;否则采用原模板*/
    if(max>Tc)  /*最大相关值大于相关门限,更新模板*/
	{
		i=newtx1;
		j=newty1;

		k=0;
        for(l=0;l<grayLevel;l++)
       		project[l]=256;

		/*寻找投影区域*/
		for(m=0;m<th;m++)
			for(n=0;n<tw;n++)
			{
				if(orgImage1[m][n]==255)
				{
					a=0;
					for(l=0;l<=k;l++)
					{
						if(orgImage2[i+m][j+n]==project[l])
						{
						    a=1;
							break;
						}
					}
					if(a==0)
					{
						project[k]=orgImage2[i+m][j+n];
						k++;
					}
				}
			}

	    for(l=0;l<k;l++)
		{
			o[l]=0;
			r[l]=0;
		}

		/*计算模板和区域的交迭面积、(和模板有交迭的)区域的面积*/
		for(l=0;l<k;l++)
		{
           	for(m=i;m<i+th;m++)
           		for(n=j;n<j+tw;n++)
				{
					if((orgImage1[m-i][n-j]==255)&&(orgImage2[m][n]==project[l]))
						o[l]++;
				}
           	for(m=sx1;m<sx2;m++)
           		for(n=sy1;n<sy2;n++)
				{
					if(orgImage2[m][n]==project[l])
						r[l]++;
				}
		}

		/*交迭比例大于交迭门限的区域加入模板*/
        for(l=0;l<k;l++)
		{
			if((float)o[l]/(float)r[l]>To)
			{
            	for(i=sx1;i<sx2;i++)
					for(j=sy1;j<sy2;j++)
					{
						if(orgImage2[i][j]==project[l])
							orgImage2[i][j]=255;
					}
			}
		}

		for(i=sx1;i<sx2;i++)
			for(j=sy1;j<sy2;j++)
			{
			   newTemplate[i-sx1][j-sy1] = 0;	
               if(orgImage2[i][j]==255) newTemplate[i-sx1][j-sy1] = 255;
//					orgImage2[i][j]=0;
			}
/* search the size of the new template */
        for(i=0; i<sx2-sx1+1; i++)
        for(j=0; j<sy2-sy1+1; j++)
           if(newTemplate[i][j]==255) 
           { *tr1 = i+sx1;  i = sx2-sx1+1; j=sy2-sy1+1;  }

        for(i=sx2-sx1+1; i>=0; i--)
        for(j=sy2-sy1+1; j>=0; j--)
           if(newTemplate[i][j]==255)
           { *tr2 = i+sx1; i=-1; j=-1;}

        for(j=0; j<sy2-sy1+1; j++)
        for(i=0; i<sx2-sx1+1; i++)
           if(newTemplate[i][j]==255)
           { *tc1=j+sy1; i=sx2-sx1+1; j=sy2-sy1+1;}
  
        for(j=sy2-sy1+1; j>=0; j--)
        for(i=sx2-sx1+1; j>=0; i--)
           if(newTemplate[i][j]==255)
           { *tc2=j+sy1; i=-1; j=-1;}
        
         ffree_2d((void **)Template,th);   orgImage1 = NULL;
         Template = newTemplate;

	}  /*End of changing template*/

//	else   /*最大相关值小于相关门限,使用原模板*/
//	{
//		for(i=0;i<imageHeight;i++)
//			for(j=0;j<imageWidth;j++)
//			    orgImage2[i][j]=orgImage1[i][j];
//
//	}
	
/*释放内存*/ 
	free(project);
	free(o);
	free(r);
    ffree_2d((void**)c,imageHeight);


}



unsigned char **Match(unsigned char **OrigImg,int Row,int Col,unsigned char **Template,int *tr1,int *tr2,int *tc1,int *tc2,int *unfind)
{
	const int grayLevel=255;
	float **c;   /*相关值*/
	float max;   /*记录最大相关值*/
	int *project;  /*投影区域*/
    unsigned char **newTemplate;
    unsigned char **orgImage1;   /* the pointer to the template */
    unsigned char **orgImage2;   /* the pointer to the original image */
    unsigned char **origImage;
    unsigned char **smoothImage;
    unsigned char **segImage;


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

	int a;

	int imageWidth;
    int imageHeight;
    int tx1,tx2,ty1,ty2;
/*搜索区域左上、右下坐标*/
	int sx1,sx2,sy1,sy2;
    int sh,sw;

	int fx1,fx2,fy1,fy2;     /*filter area*/
	int fh,fw;

/*模板上、下、左、右坐标    模板数据从(0,0)至(th-1,tw-1),tx1,tx2,ty1,ty2用来确定搜索区域*/
	int tx0,ty0;   /*模板中心位置*/
	int th,tw;     /*模板尺寸*/
	int t;         /*模板面积*/

	int newtx1,newty1;  /*新模板左上坐标*/

	float Tc=0.96;       /*相关门限*/
    float To=0.69;   	/*交迭门限*/


/*模板和区域的交迭面积、和模板交迭的区域面积*/
	int *o;
	int *r;
    
    imageHeight = Row;
    imageWidth  = Col;
    orgImage2 = OrigImg;   /* orgImage2 is original grey level image */
    orgImage1 = Template;  /* orgImage1 is the template data with size th*tw */

    tx1 = *tr1;
    tx2 = *tr2;
    ty1 = *tc1;
    ty2 = *tc2;

	th=tx2-tx1+1;
	tw=ty2-ty1+1;
	tx0=(tx1+tx2)/2;     /*简单的中心位置*/
	ty0=(ty1+ty2)/2;

	if(*unfind<5)
	{
    	sx1=tx0-th*2/3;   
    	sx2=tx0+th*2/3;
    	sy1=ty0-tw*2/3;
    	sy2=ty0+tw*2/3;
    	fx1=tx0-th;   
    	fx2=tx0+th;
    	fy1=ty0-tw;
    	fy2=ty0+tw;

	}
	else 
	{
    	sx1=tx0-th;   
    	sx2=tx0+th;
    	sy1=ty0-tw;
    	sy2=ty0+tw;
    	fx1=tx0-th*4/3;   
    	fx2=tx0+th*4/3;
    	fy1=ty0-tw*4/3;
    	fy2=ty0+tw*4/3;

	}

	if(sx1<0)
		sx1=0;
	if(sx2>=imageHeight)
		sx2=imageHeight-1;
	if(sy1<0)
		sy1=0;
	if(sy2>=imageWidth)
		sy2=imageWidth-1;
    sh = sx2-sx1+1;
    sw = sy2-sy1+1;

	if(fx1<0)
		fx1=0;
	if(fx2>=imageHeight)
		fx2=imageHeight-1;
	if(fy1<0)
		fy1=0;
	if(fy2>=imageWidth)
		fy2=imageWidth-1;
    fh = fx2-fx1+1;
    fw = fy2-fy1+1;


/*分配内存*/
	c=(float**)fspace_2d(imageHeight,imageWidth,sizeof(float));
    project=(int*)malloc(grayLevel*sizeof(int));
    o=(int*)malloc(grayLevel*sizeof(int));
    r=(int*)malloc(grayLevel*sizeof(int));


/* extract the search window  */
    origImage = (unsigned char **)fspace_2d(fh,fw,sizeof(unsigned char));
    smoothImage = (unsigned char **)fspace_2d(fh,fw,sizeof(unsigned char));
    segImage = (unsigned char **)fspace_2d(fh,fw,sizeof(unsigned char));
    if(!smoothImage | !segImage | !origImage)
    {
       return NULL;
    }
   
    for(i=fx1; i<=fx2; i++)  /* extract sub-image from the orginal image */
    for(j=fy1; j<=fy2; j++)
       origImage[i-fx1][j-fy1] = OrigImg[i][j];
    HOF(origImage,smoothImage,fh,fw);
    HOS(smoothImage,segImage,fh,fw);
    for(i=fx1; i<=fx2; i++)    /* write the processed data back to original image */
    for(j=fy1; j<=fy2; j++)
       OrigImg[i][j] = segImage[i-fx1][j-fy1];    

/*计算模板面积*/
    t=0;
	for(m=0;m<th;m++)
		for(n=0;n<tw;n++)
		{
			if(orgImage1[m][n]==255)
			    t++;
		}



/*计算相关值*/
	for(i=sx1;i<sx2-th;i++)
		for(j=sy1;j<sy2-tw;j++)
			c[i][j]=0.0;
    
	for(i=sx1;i<sx2-th;i++)
		for(j=sy1;j<sy2-tw;j++)
		{
            k=0;
        	for(l=0;l<grayLevel;l++)
        		project[l]=255;

		/*寻找投影区域*/
			for(m=0;m<th;m++)
				for(n=0;n<tw;n++)
				{
					if(orgImage1[m][n]==255)
					{
						a=0;    /*a=0表示新区域*/
						for(l=0;l<=k;l++)    /*判别是否为新区域*/
						{
							if(orgImage2[i+m][j+n]==(unsigned char)project[l])
							{
							    a=1;
								break;
							}
						}
						if(a==0)
						{
							project[k]=orgImage2[i+m][j+n];
							k++;
						}
					}
				}


		    for(l=0;l<k;l++)
			{
				o[l]=0;
				r[l]=0;
			}

		/*计算模板和区域的交迭面积、(和模板有交迭的)区域的面积*/
			for(l=0;l<k;l++)
			{
            	for(m=i;m<i+th;m++)
            		for(n=j;n<j+tw;n++)
					{
						if((orgImage1[m-i][n-j]==255)&&(orgImage2[m][n]==project[l]))
							o[l]++;
					}
            	for(m=sx1;m<sx2;m++)
            		for(n=sy1;n<sy2;n++)
					{
						if(orgImage2[m][n]==project[l])
							r[l]++;
					}
			}

		/*计算相关值*/
			for(l=0;l<k;l++)
				c[i][j]=c[i][j]+(float)(o[l]*o[l])/(float)r[l];

			c[i][j]=c[i][j]/(float)t;

		}

/*寻找最大相关值*/

⌨️ 快捷键说明

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