📄 improc.cpp
字号:
start_i = start_j = margin;
end_i = row - margin;
end_j = col - margin;
for(i=0;i<256;i++) d[i] = 0.0;
for(i=start_i;i<end_i;i++)
for(j=start_j;j<end_j;j++)
d[(int)(ratio*(a[i][j]-min))] += 1.0;
total = (double)(row-margin*2)*(double)(col-margin*2);
for(i=0;i<256;i++) d[i] /= total;
}
void Sobel(unsigned char **a,int YStart,int XStart,int row,int col,double **e,
double **d,int SobelMode)
{
register int i,j;
int row2,col2,sum1,sum2;
double x,y;
row2 = row-2;
col2 = col-2;
for(i=YStart+1;i<=YStart+row2;i++)
for(j=XStart+1;j<=XStart+col2;j++) {
sum1 = (int)a[i+1][j-1]+2*(int)a[i+1][j]+(int)a[i+1][j+1];
sum2 = (int)a[i-1][j-1]+2*(int)a[i-1][j]+(int)a[i-1][j+1];
y=(double)(sum1-sum2);
sum1 = (int)a[i-1][j+1]+2*(int)a[i][j+1]+(int)a[i+1][j+1];
sum2 = (int)a[i-1][j-1]+2*(int)a[i][j-1]+(int)a[i+1][j-1];
x = (double)(sum1-sum2);
/* get the magnitude of the grade image */
e[i-YStart][j-XStart] = (double)sqrt(x*x+y*y);
/* get the direction of the grade image */
if (SobelMode==GETDIRECTION)
{
double pid = 180.0/3.14;
if ((x==0.0) && (y==0.0))
d[i-YStart][j-XStart] = 720.0;
else
d[i-YStart][j-XStart] = (double)atan2(y,x)*pid;
}
}
}
/************************** NORMALIZEGRAYLEVEL ***********************/
/* Normalize the graylevel of image Image */
/* Normalize definition is : */
/* Image[i][j] = (Image[i][j]-IMin)/(IMax-IMin)*(Max-Min)+Min */
double **NormalizeGraylevel(unsigned char **Image,int Row,int Col,int Min,int Max)
{
int i,j,IMax,IMin;
double **NormalizedImage;
NormalizedImage = (double **)fspace_2d(Row,Col,sizeof(double));
IMax = ucMax2d(Image,Row,Col,0,&IMin);
for(i=0;i<Row;i++)
for(j=0;j<Col;j++)
NormalizedImage[i][j] = (double)(Image[i][j]-IMin) / (IMax-IMin) * (Max-Min) + Min;
return(NormalizedImage);
}
/************************** NORMALIZEdouble ***************************/
/* Normalize the double array */
/* Normalize definition is : */
/* Image[i][j] = (double[i][j]-IMin)/(IMax-IMin)*(Max-Min)+Min */
unsigned char **Normalizedouble(double **Db,int Row,int Col,int Min,int Max,
int Margin)
{
int i,j;
unsigned char **NormalizedImage;
double FMax,FMin;
NormalizedImage = (unsigned char **)fspace_2d(Row,Col,sizeof(unsigned char));
FMax = fMax2d(Db,Row,Col,Margin,&FMin);
for(i=Margin;i<Row-Margin;i++)
for(j=Margin;j<Col-Margin;j++)
NormalizedImage[i][j] =(unsigned char) ( (Db[i][j]-FMin) / (FMax-FMin) * (Max-Min) + Min );
return(NormalizedImage);
}
/*********************** CONTRASTENHANCEMENT ***************************/
/* Non linear contrast enhancement */
unsigned char **ContrastEnhancement(unsigned char **Image,int Row,int Col,
int Eb)
{
unsigned char **EnhancementImage;
int i,j,Tem;
EnhancementImage = (unsigned char **)fspace_2d(Row,Col,sizeof(unsigned char));
for(i=0;i<Row;i++)
for(j=0;j<Col;j++)
{
Tem = Image[i][j] - Eb;
if (Tem<0)
EnhancementImage[i][j] = 0;
else if (Tem<15)
EnhancementImage[i][j] = Tem * Tem;
else
EnhancementImage[i][j] = 255;
}
return(EnhancementImage);
}
/**************************** GRAYTRANS ********************************/
/* Get non linear graylevel transform palette */
void GrayTrans(int *GrayTransMask,unsigned char *Palette,int Current,
int Lower,int Upper)
{
int i;
for(i=Lower;i<=Current;i++)
Palette[i] = (double)(i - Lower)
* (GrayTransMask[Current] - GrayTransMask[Lower])
/ (Current - Lower)
+ GrayTransMask[Lower] + 0.5;
for(i=Current;i<=Upper;i++)
Palette[i] = (double)(i - Current)
* (GrayTransMask[Upper] - GrayTransMask[Current])
/ (Upper - Current)
+ GrayTransMask[Current] + 0.5;
}
/*******************************************************/
/* Calculate the correlation map */
/* Written by YANG Weidong */
/*******************************************************/
double** CalCorMap(unsigned char** ref, unsigned char** rel, int r1, int c1, int r2, int c2)
{
int mr;
int mc;
double SumX ,SumY , SumYY, SumXX , SumXY;
int counts = 0;
double** ret;
int i,j,m,n;
mr = r1-r2 + 1;
mc = c1-c2 + 1;
/* ret = (double ** )fspace_2d(mr,mc, sizeof(double)); */
ret = (double**)fspace_2d(r1,c1,sizeof(double));
SumX = SumXX = 0;
for (i=0;i<r2;i++)
for (j=0;j<c2;j++)
{
SumX += rel[i][j];
SumXX += rel[i][j]*rel[i][j];
counts ++;
}
SumXX -= SumX*SumX/counts;
for ( i=0;i<mr;i++)
for ( j=0;j<mc;j++)
{
SumY = SumYY = SumXY = 0;
for ( m=0;m<r2;m++)
for ( n=0;n<c2;n++)
{
SumXY += ref[i+m][j+n] * rel[m][n];
SumY += ref[i+m][j+n];
SumYY += ref[i+m][j+n] * ref[i+m][j+n];
}
SumYY -= SumY*SumY/counts;
SumXY -= SumX*SumY/counts;
ret[i+mr/2][j+mc/2] = (double) SumXY / sqrt(SumXX*SumYY);
}
return ret;
}
void HOF(unsigned char **OrigImg, unsigned char **SmoothImg, int Row, int Col)
{
const int grayLevel=256;
int i,j;
int k,m;
int n=1; /*平滑窗口尺寸*/
int x=0; /*记录迭代次数*/
int s; /*记录和值的临时变量*/
int h0; /*记录中心区域的均匀性*/
int h1; /*记录左上区域的均匀性*/
int h2; /*记录右上区域的均匀性*/
int h3; /*记录左下区域的均匀性*/
int h4; /*记录右下区域的均匀性*/
int imageWidth; /*波门尺寸*/
int imageHeight;
int a; /*标记循环是否结束?a=1时迭代结束*/
unsigned char **aveImage; /*图像的固定尺寸平均值*/
unsigned char **smoothImage1; /*前一次迭代平滑的结果*/
unsigned char **smoothImage2; /*本次迭代平滑的结果*/
imageHeight=Row;
imageWidth=Col;
aveImage=(unsigned char**)fspace_2d(imageHeight,imageWidth,sizeof(unsigned char));
smoothImage1=(unsigned char**)fspace_2d(imageHeight,imageWidth,sizeof(unsigned char));
smoothImage2=(unsigned char**)fspace_2d(imageHeight,imageWidth,sizeof(unsigned char));
/*start to iterately smoothing*/
for(i=0; i<imageHeight; i++)
for(j=0; j<imageWidth; j++) smoothImage1[i][j] = OrigImg[i][j];
a=0; /*标记循环是否结束?*/
while(a==0)
{
/*求取图像的固定尺寸平均值*/
for(i=n;i<imageHeight-n;i++)
for(j=n;j<imageWidth-n;j++)
{
s=0;
for(k=i-n;k<=i+n;k++)
for(m=j-n;m<=j+n;m++)
s=s+smoothImage1[k][m];
aveImage[i][j]=s/((2*n+1)*(2*n+1));
}
for(i=0;i<n;i++)
for(j=0;j<imageWidth;j++)
aveImage[i][j]=aveImage[i+n][j];
for(i=imageHeight-n;i<imageHeight;i++)
for(j=0;j<imageWidth;j++)
aveImage[i][j]=aveImage[i-n][j];
for(j=0;j<n;j++)
for(i=0;i<imageHeight;i++)
aveImage[i][j]=aveImage[i][j+n];
for(j=imageWidth-n;j<imageWidth;j++)
for(i=0;i<imageHeight;i++)
aveImage[i][j]=aveImage[i][j-n];
/*对每一点,寻找五个区域中均匀性最好的区域,并以此区域的平均值作为平滑值*/
for(i=2*n;i<imageHeight-2*n;i++)
for(j=2*n;j<imageWidth-2*n;j++)
{
/*求五个区域的均匀性*/
h0=abs(aveImage[i+n][j-n]+aveImage[i+n][j+n]-aveImage[i-n][j-n]-aveImage[i-n][j+n])+
abs(aveImage[i-n][j+n]+aveImage[i+n][j+n]-aveImage[i-n][j-n]-aveImage[i+n][j-n]);
h1=abs(aveImage[i][j-2*n]+aveImage[i][j]-aveImage[i-2*n][j-2*n]-aveImage[i-2*n][j])+
abs(aveImage[i-2*n][j]+aveImage[i][j]-aveImage[i-2*n][j-2*n]-aveImage[i][j-2*n]);
h2=abs(aveImage[i][j]+aveImage[i][j+2*n]-aveImage[i-2*n][j]-aveImage[i-2*n][j+2*n])+
abs(aveImage[i-2*n][j+2*n]+aveImage[i][j+2*n]-aveImage[i-2*n][j]-aveImage[i][j]);
h3=abs(aveImage[i+2*n][j-2*n]+aveImage[i+2*n][j]-aveImage[i][j-2*n]-aveImage[i][j])+
abs(aveImage[i][j]+aveImage[i+2*n][j]-aveImage[i][j-2*n]-aveImage[i+2*n][j-2*n]);
h4=abs(aveImage[i+2*n][j]+aveImage[i+2*n][j+2*n]-aveImage[i][j]-aveImage[i][j+2*n])+
abs(aveImage[i][j+2*n]+aveImage[i+2*n][j+2*n]-aveImage[i][j]-aveImage[i+2*n][j]);
/*寻找五个区域中均匀性最好的区域,并以此区域的平均值作为平滑值*/
if((h0<=h1)&&(h0<=h2)&&(h0<=h3)&&(h0<=h4))
smoothImage2[i][j]=aveImage[i][j];
else if((h1<=h0)&&(h1<=h2)&&(h1<=h3)&&(h1<=h4))
smoothImage2[i][j]=aveImage[i-n][j-n];
else if((h2<=h0)&&(h2<=h1)&&(h2<=h3)&&(h2<=h4))
smoothImage2[i][j]=aveImage[i-n][j+n];
else if((h3<=h0)&&(h3<=h1)&&(h3<=h2)&&(h3<=h4))
smoothImage2[i][j]=aveImage[i+n][j-n];
else if((h4<=h0)&&(h4<=h1)&&(h4<=h2)&&(h4<=h3))
smoothImage2[i][j]=aveImage[i+n][j+n];
}
for(i=0;i<2*n;i++)
for(j=0;j<imageWidth;j++)
smoothImage2[i][j]=smoothImage2[2*n][j];
for(i=imageHeight-2*n;i<imageHeight;i++)
for(j=0;j<imageWidth;j++)
smoothImage2[i][j]=smoothImage2[imageHeight-2*n-1][j];
for(i=0;i<imageHeight;i++)
for(j=0;j<2*n;j++)
smoothImage2[i][j]=smoothImage2[i][2*n];
for(i=0;i<imageHeight;i++)
for(j=imageWidth-2*n;j<imageWidth;j++)
smoothImage2[i][j]=smoothImage2[i][imageWidth-2*n-1];
x++;
if(x==5) a=1; /*迭代5次*/
else
{
for(i=0;i<imageHeight;i++)
for(j=0;j<imageWidth;j++)
smoothImage1[i][j]=smoothImage2[i][j];
}
} /*End of while*/
/*saving the smoothed data */
for(i=0;i<imageHeight;i++)
for(j=0;j<imageWidth;j++)
SmoothImg[i][j]=smoothImage2[i][j];
/*free the unused memmory*/
ffree_2d((void**)aveImage,imageHeight);
ffree_2d((void**)smoothImage1,imageHeight);
ffree_2d((void**)smoothImage2,imageHeight);
}
//*******************************************************************//
// //
// HOS算法 //
// //
//*******************************************************************//
void HOS(unsigned char **orgImage, unsigned char **resImage,int imageHeight,int imageWidth)
{
const int grayLevel=256;
int *subline; /*记录每一行的子段个数*/
int **location; /*记录每一子段的起始列位置,location[i][j]表示第i行的第j个子段的起始列位置*/
int **label; /*初始标记——即按行标记的结果*/
int **newImage; /*结果图像*/
int T=4; /*灰度差门限*/
int overlap1,overlap2; /*交迭的起始子段和终止子段*/
int min,minLabel; /*记录相邻两行交迭子段起始点最小差值及位置*/
int i,j; /*循环变量*/
int l; /*循环变量*/
int k; /*循环变量*/
/*分配内存*/
subline=(int*)malloc(imageHeight*sizeof(int));
location=(int**)fspace_2d(imageHeight,imageWidth,sizeof(int));
label=(int**)fspace_2d(imageHeight,imageWidth,sizeof(int));
newImage=(int**)fspace_2d(imageHeight,imageWidth,sizeof(int));
// orgImage=(int**)fspace_2d(imageHeight,imageWidth,sizeof(int));
/*取窗口数据*/
// for(i=xx1;i<xx2;i++)
// for(j=yy1;j<yy2;j++)
// orgImage[i-xx1][j-yy1]=orgImage0[i][j];
/*对原始图像进行初始标记——按行进行标记*/
for(i=0;i<imageHeight;i++)
{
label[i][0]=0; /*每行的初始标记均从0开始*/
location[i][0]=0; /*每行的第0个子段的起始位置均为第0列*/
k=0; /*每行的标记值*/
for(j=1;j<imageWidth;j++)
{
if(abs(orgImage[i][j]-orgImage[i][j-1])<T) /*减前一像素抑或减此子段的起始像素?*/
label[i][j]=label[i][j-1]; /*也可写成label[i][j]=k;*/
else
{
k++;
location[i][k]=j;
label[i][j]=k;
}
}
k++;
location[i][k]=imageWidth; /*设一虚假结束点*/
subline[i]=k;
}
/*根据初始标记结果,按列对图像进行标记*/
/*第一行按初始标记进行最终标记*/
for(j=0;j<imageWidth;j++)
newImage[0][j]=label[0][j];
k=subline[0]; /*整体标记*/
for(i=1;i<imageHeight;i++)
{
/*对每一行的每一子段进行处理*/
for(j=0;j<subline[i];j++)
{
/*查找与此子段有交迭的上行起始标记*/
for(l=0;l<=subline[i-1];l++)
{
if(location[i][j]+1<location[i-1][l])
{
overlap1=l-1;
break;
}
}
/*查找与此子段有交迭的上行终止标记*/
for(l=0;l<=subline[i-1];l++)
{
if(location[i][j+1]-2<location[i-1][l])
{
overlap2=l-1;
break;
}
}
/*选取相邻两行有交迭的子段起始点之间的最小差值,并判别是否小于门限T*/
min=256;
for(l=overlap1;l<=overlap2;l++)
if(abs(orgImage[i][location[i][j]]-orgImage[i-1][location[i-1][l]])<min)
{
min=abs(orgImage[i][location[i][j]]-orgImage[i-1][location[i-1][l]]);
minLabel=l;
}
/*如果最小差值小于门限,将此子段标记为最类似的上行子段一样的标记*/
if(min<T)
{
for(l=location[i][j];l<location[i][j+1];l++)
newImage[i][l]=newImage[i-1][location[i-1][minLabel]];
}
/*也可根据初始标记进行循环
for(l=0;l<imageWidth;l++)
{
if(label[i][l]==j)
newImage[i][l]=newImage[i-1][location[i-1][minLabel]];
}
*/
/*如果最小差值大于门限,将此子段标为新标记*/
else
{
k=(k+1)%256;
for(l=location[i][j];l<location[i][j+1];l++)
newImage[i][l]=k;
}
} /*行的结束*/
}
/*保存图像*/
for(i=0;i<imageHeight;i++)
for(j=0;j<imageWidth;j++)
resImage[i][j]=newImage[i][j];
/*释放内存*/
free(subline);
ffree_2d((void**)location,imageHeight);
ffree_2d((void**)label,imageHeight);
ffree_2d((void**)newImage,imageHeight);
}
//*******************************************************************//
// //
// Match算法 //
// //
//*******************************************************************//
void Match1(unsigned char **OrigImg,int Row,int Col,int sr0,int sc0,unsigned char **Template,int *tr1,int *tr2,int *tc1,int *tc2)
{
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 */
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -