📄 global.cpp
字号:
evs[maxnum]=mini-1.0;
order[i]=(WORD)maxnum;
}
delete evs;
}
/////////order the values///////////////////
//when return, order[i] is the bianhao in the original array;
// No[i] is the bianhao in the new order array!
void NewOrder(double* ev, WORD* order, WORD* No, WORD M)
{
BYTE i,j,maxnum;
double* evs;
double mini,maxi;
evs=new double[M];
mini=*ev;
for(i=0;i<M;i++)
{
evs[i]=*(ev+i);
if(evs[i]<mini) mini=evs[i];
order[i]=i;
}
for(i=0;i<M;i++)
{
maxi=evs[i];
maxnum=i;
for(j=0;j<M;j++)
{
if(evs[j]>maxi)
{
maxi=evs[j];
maxnum=j;
}
}
evs[maxnum]=mini-1.0;
order[i]=maxnum;
}
for(i=0;i<M;i++)
No[order[i]] = i;
delete evs;
}
//I wonder wh the following function is modified!!
//It has logic errors!!
/*//////////////////////////////////////////////////
void OrderValues(double* ev, WORD* order, WORD M)
{
WORD i,j,maxnum;
double *evs, *vec;
double mini,maxi;
evs = new double[M];
vec = new double[M];
mini = *ev;
for(i=0; i<M; i++)
{
evs[i] = *(ev + i);
if(evs[i] < mini)
mini = evs[i];
order[i] = i;
}
for(i=0; i<M; i++)
{
maxi = evs[i];
maxnum = i;
for(j=0; j<M; j++)
{
if(evs[j]>maxi)
{
maxi = evs[j];
maxnum = j;
}
}
evs[maxnum] = mini-1.0;
order[i] = maxnum;
}
for(i=0; i<M; i++)
vec[i] = ev[order[i]];
for(i=0; i<M; i++)
ev[i] = vec[i];
delete evs;
delete vec;
}
*////////////////////////////////////////////////////////////////
double Project(CPtrArray* pfaEF, double* pMeanFace, BYTE* pImageData,
double* pProjectVector, DWORD dwImageSize, WORD wEigenFaceNum)
{
WORD i;
double* pf = new double[dwImageSize];
if(!pf) {
AfxMessageBox("Project(): new memory error!");
return 0;
}
for(i=0; i<dwImageSize; i++) //convert data to double number
pf[i] = (double) pImageData[i];
double dd = NormalVector(pf, dwImageSize); //normalize the Image
for(i=0; i<dwImageSize; i++) //diff it
pf[i] -= pMeanFace[i];
for(i=0; i<wEigenFaceNum; i++) //project it to the face space
pProjectVector[i] = InnerProduct(pf, (double*)pfaEF->GetAt(i), dwImageSize);
delete pf;
return dd;
}
////////////////////////////////////////////////////////////////////////
//author: ssg Time: 1998.5.4
//欧式距离
//////////////////////////////////////////////////////////////////////////
double EuclidDistance(double* pv1, double* pv2, DWORD Length)
{
DWORD i;
double dis = 0.0;
for(i=0; i<Length; i++)
dis += (pv1[i] - pv2[i]) * (pv1[i] - pv2[i]);
dis = (double)sqrt(dis);
return dis;
}
////////////////////////////////////////////////////////////////////////
//author: ssg Time: 1998.7.6
//两点距离
//////////////////////////////////////////////////////////////////////////
double PointDistance(CPoint p1, CPoint p2)
{
return (double) sqrt((p2.y-p1.y) * (p2.y-p1.y) + (p2.x-p1.x) * (p2.x-p1.x));
}
////////////////////////////////////////////////////////////////////////
//author: ssg Time: 1998.5.4
//用特征脸恢复原图像
//////////////////////////////////////////////////////////////////////////
BOOL RevertImage(CPtrArray* pfaEF, double* pMeanFace, BYTE* pImageData,
double* project, DWORD dwImageSize, WORD wEigenFaceNum)
{
WORD i;
DWORD j;
double dd;
double* pEigen;
double ave = Project(pfaEF, pMeanFace, pImageData, project, dwImageSize, wEigenFaceNum);
double* pf = new double[dwImageSize];
if(!pf) {
AfxMessageBox("New memory error!");
return false;
}
for(j=0; j<dwImageSize; j++)
pf[j] = 0.0;
for(i=0; i<wEigenFaceNum; i++)
{
pEigen = (double*) pfaEF->GetAt(i);
for(j=0; j<dwImageSize; j++)
pf[j] += project[i] * pEigen[j];
}
for(j=0; j<dwImageSize; j++)
pf[j] += pMeanFace[j];
for(j=0; j<dwImageSize; j++)
{
dd = pf[j] * ave;
if(dd < 255.0)
pImageData[j] = (BYTE)dd;
else
pImageData[j] = 255;
}
delete pf;
return true;
}
////////////////////////////////////////////////////////////////////////
//author: ssg Time: 1998.5.4
////////////////////////////////////////////////////////////////
double DistanceFromFaceSpace(CPtrArray* pfaEF, double* pMeanFace, BYTE* pImageData,
DWORD dwImageSize, WORD wEigenFaceNum)
{
WORD i;
DWORD j;
double dis;
double* pEigen;
double* project = new double[wEigenFaceNum];
double* pfold = new double[dwImageSize];
double* pfnew = new double[dwImageSize];
if(!pfnew || !project || !pfold) {
AfxMessageBox("New memory error!");
return -1;
}
//the old iamge
for(j=0; j<dwImageSize; j++)
pfold[j] = (double)pImageData[j];
NormalVector(pfold, dwImageSize);
for(j=0; j<dwImageSize; j++)
pfold[j] -= pMeanFace[j];
//project it to the face space
for(i=0; i<wEigenFaceNum; i++)
project[i] = InnerProduct(pfold, (double*)pfaEF->GetAt(i), dwImageSize);
//revert the image
for(j=0; j<dwImageSize; j++)
pfnew[j] = 0.0;
for(i=0; i<wEigenFaceNum; i++)
{
pEigen = (double*) pfaEF->GetAt(i);
for(j=0; j<dwImageSize; j++)
pfnew[j] += project[i] * pEigen[j];
}
//cal the distance
dis = EuclidDistance(pfold, pfnew, dwImageSize);
delete project;
delete pfold;
delete pfnew;
return dis;
}
void GetSubImageData(BYTE* scrImgData, BYTE* destImgData, WORD scrW, WORD scrH, CPoint start,CSize size)
{
if( ((size.cx + start.x) > scrW ) || ((size.cy+start.y) > scrH) )
{
AfxMessageBox("sub-Image size is too large!");
return;
}
int i;
BYTE* p1; BYTE* p2;
BYTE* pData = (BYTE*) (scrImgData + (start.y * scrW + start.x) );
for(i=0 ; i<(int)size.cy ; i++)
{
p1 = pData + i * scrW;
p2 = destImgData + i * size.cx;
memcpy(p2 , p1 , size.cx);
}
}
BOOL IsSamePeople(CString s1, CString s2)
{
s1.MakeLower();
s2.MakeLower();
CString ss1 = s1.Mid(0, 3);
CString ss2 = s2.Mid(0, 3);
if(ss1 == ss2)
return true;
return false;
}
void GetHisName(CString filename, CString& HisName)
{
int n = 2;
if(filename.GetAt(2) == '1' || filename.GetAt(2) == '2' )
n = 3;
HisName = filename.Mid(n, 3);
}
/*
**
** Robot Vision Group
** Dept. of Artificial Intelligence
** University of Edinburgh
**
** Authors: Bob Fisher, Dave Croft, A Fitzgibbon
** Date: September 86
** Program: canny.c
** Current Maintainer: andrewfg@ed.ac.uk
**
** Modified by Xilin, Chen
** Vilab, Dept. of Computer Sci.
** Harbin Institute of Technology
**Date: September 97
**
** Purpose: to apply a simple symmetric canny operator to any size image
**
**/
void CannyEdge(double Sigma, int Width, int Height, uchar *Img,
uchar *PotentialEdge, uchar *EdgeIntensity,
uchar *EdgeDir)
//////////////////////////////////////////////////////////////////////////////
// Sigma ---- standard deviation
// Width, Height ---- picture dimensions
// Img ---- Original Image
// PotentialEdge ----
// EdgeIntensity ---- Intensity Edge. If EdgeIntensity is null, then no output
// EdgeDir ---- Edge Orientation. If Edge is null, then no Orientation output
//////////////////////////////////////////////////////////////////////////////
{
int FilterWidth; /* length of 1-D Gaussian mask */
float *gSmooth_x, *gSmooth_y;
float *Diff_y, *Diff_x;
int i, k, n; /* counters */
int t; /* temp. grad EdgeIntensity variable */
double a, b, c, d, g0; /* mask generation intermediate vars*/
double ux, uy;
double t1, t2;
double G[MAX_FILTER_WIDTH], dG[MAX_FILTER_WIDTH];
// double D2G[MAX_FILTER_WIDTH]; /*Gaussian & derivative filter masks*/
double gc, gn, gs, gw, ge, gnw, gne, gsw, gse;
int ImgSize, jstart, jlimit;
int ilimit;
register jfactor;
int kfactor1, kfactor2;
int kfactor;
register cindex, nindex, sindex, windex, eindex, nwindex, neindex, swindex, seindex;
int low = 1, high = 255; /* tracker hysteresis parameters */
int mag_overflow_count = 0; /* used to measure how oft mag array overflows */
int mag_underflow_count = 0; /* used to measure how oft mag array underflows */
ImgSize = Width * Height; /* picture area */
/* calc coeffs for 1-dimensional G, dG/dn and Delta-squared G filters */
for (n = 0; n < MAX_FILTER_WIDTH; ++n) {
a = Gaussian(((double) n),Sigma);
if (a>0.005 || n<2) {
b = Gaussian((double)n - 0.5, Sigma);
c = Gaussian((double)n + 0.5, Sigma);
d = Gaussian((double)n, Sigma * 0.5);
fprintf(stderr,"a,b,c: %lf,%lf,%lf\n",a,b,c);
G[n] = (a+b+c)/3/(6.283185*Sigma*Sigma); // (a+b+c)/3 for more stability
dG[n] = c - b;
// D2G[n] = 1.6 * d - a; /* DOG */
// fprintf(stderr,"G[%d]: %lf\n",n,G[n]);
// fprintf(stderr,"dG[%d]: %lf\n",n,dG[n]);
// fprintf(stderr,"D2G[%d]: %lf\n",n,D2G[n]);
}
else break;
}
FilterWidth = n;
fprintf(stderr,"canny_core: smooth pic\n");
/* allocate space for Gaussian smoothing arrays */
if ((gSmooth_x = (float *)calloc(ImgSize,sizeof(float)))==(float *)NULL) {
fprintf(stderr,"can't alloc gsmooth_x\n");
exit(0);
}
if ((gSmooth_y = (float *)calloc(ImgSize,sizeof(float)))==(float *)NULL) {
fprintf(stderr,"can't alloc gsmooth_y\n");
exit(0);
}
/* produce x- and y- convolutions with Gaussian */
// gSmooth_x(z,y) = Img(x,y) * G(x)
// gSmooth_y(x,z) = Img(x,y) * G(y)
ilimit = Width - (FilterWidth - 1);
jstart = Width * (FilterWidth - 1);
jlimit = Width * (Height - (FilterWidth - 1));
for (i = FilterWidth - 1; i < ilimit; ++i) {
for (jfactor = jstart; jfactor < jlimit; jfactor+=Width) {
cindex = i + jfactor;
t1 = Img[cindex] * G[0];
t2 = t1;
for (k = 1, kfactor1=cindex-Width, kfactor2=cindex+Width; k<FilterWidth;
k++, kfactor1-=Width, kfactor2+=Width) {
t1 += G[k] * (Img[kfactor1] + Img[kfactor2]);
t2 += G[k] * (Img[cindex-k] + Img[cindex+k]);
}
gSmooth_x[cindex]=(float)t1; // column convolution, smooth with Gauss
gSmooth_y[cindex]=(float)t2; // row convolution, smooth with Gauss
}
}
/* allocate space for gradient arrays */
fprintf(stderr,"canny_core: find grad\n");
if ((Diff_y = (float *)calloc(ImgSize, sizeof(float))) == (float *)NULL) {
fprintf(stderr,"can't alloc x\n");
exit(0);
}
/* produce x and y convolutions with derivative of Gaussian */
// Diff_y(x,z) = gSmooth_x(x,y) * dG(y)
for (i = FilterWidth-1; i < ilimit; ++i) {
for (jfactor = jstart; jfactor < jlimit; jfactor+=Width) {
t1=0;
cindex=i+jfactor;
for (k = 1; k < FilterWidth; ++k)
t1 += dG[k] * (gSmooth_x[cindex-k] - gSmooth_x[cindex+k]);
Diff_y[cindex] = (float)t1;
}
}
free(gSmooth_x);
// Diff_x(z,y) = gSmooth_y(x,y) * dG(x)
if ((Diff_x=(float *)calloc(ImgSize,sizeof(float)))==(float *)NULL) {
fprintf(stderr,"can't alloc y\n");
exit(0);
}
for (i = n; i < Width - n; ++i) {
for (jfactor = jstart; jfactor < jlimit; jfactor += Width) {
t2 = 0;
cindex = i + jfactor;
for (k = 1, kfactor = Width; k < FilterWidth; k++, kfactor += Width)
t2 += dG[k] * (gSmooth_y[cindex-kfactor]-gSmooth_y[cindex+kfactor]);
Diff_x[cindex] = (float)t2;
}
}
free(gSmooth_y);
/* non-maximum suppression (4 cases for EdgeDir of line of max slope) */
fprintf(stderr,"canny_core: non-maximum suppression\n");
ilimit = Width - FilterWidth;
jstart = Width * FilterWidth;
jlimit = Width * (Height - FilterWidth);
for (i = FilterWidth; i < ilimit; ++i) {
for (jfactor = jstart; jfactor < jlimit; jfactor += Width) {
/* calculate current indeces */
cindex=i+jfactor;
nindex=cindex-Width; sindex=cindex+Width;
windex=cindex-1; eindex=cindex+1;
nwindex=nindex-1; neindex=nindex+1;
swindex=sindex-1; seindex=sindex+1;
ux=Diff_y[cindex]; uy=Diff_x[cindex];
gc=hypotenuse(ux,uy);
/* scale gc to fit into an unsigned char array */
t = (int)(gc*20.0);
/*fprintf(stderr,"canny_core: i,j=(%d,%d), t=%lf\n",i,jfactor/Width,t);*/
PotentialEdge[cindex] = (t<256 ? t : 255);
gn = hypotenuse(Diff_y[nindex], Diff_x[nindex]);
gs = hypotenuse(Diff_y[sindex], Diff_x[sindex]);
gw = hypotenuse(Diff_y[windex], Diff_x[windex]);
ge = hypotenuse(Diff_y[eindex],Diff_x[eindex]);
gne = hypotenuse(Diff_y[neindex],Diff_x[neindex]);
gse=hypotenuse(Diff_y[seindex],Diff_x[seindex]);
gsw=hypotenuse(Diff_y[swindex],Diff_x[swindex]);
gnw=hypotenuse(Diff_y[nwindex],Diff_x[nwindex]);
if (ux*uy>0) {
if (fabs(ux) < fabs(uy)) {
g0 = fabs(uy*gc);
if(g0 < fabs(ux*gse+(uy-ux)*gs) || g0 <= fabs(ux*gnw+(uy-ux)*gn))
continue;
}
else {
g0 = fabs(ux*gc);
if(g0 < fabs(uy*gse+(ux-uy)*ge) || g0<=fabs(uy*gnw+(ux-uy)*gw))
continue;
}
}
else {
if(fabs(ux)<fabs(uy)) {
g0=fabs(uy*gc);
if(g0 < fabs(ux*gne-(uy+ux)*gn) || g0<=fabs(ux*gsw-(uy+ux)*gs))
continue;
}
else {
g0=fabs(ux*gc);
if(g0 < fabs(uy*gne-(ux+uy)*ge) || g0<=fabs(uy*gsw-(ux+uy)*gw))
continue;
}
}
/* seems to be a good scale factor */
if (EdgeIntensity != NULL)
EdgeIntensity[cindex] = PotentialEdge[cindex];
/* pi*40 ~= 128 - direction is (thought of as) a signed byte */
if (EdgeDir != NULL)
EdgeDir[cindex] = (uchar)(atan2(uy, ux)*ORIENT_SCALE);
}
}
free(Diff_y);
free(Diff_x);
}
// Subroutines used by *canny progs (but not by *canny_j progs)
// hypot can't cope when both it's args are zero, hence this hack....
double hypotenuse(double x, double y)
{
if (x==0.0 && y==0.0)
return(0.0);
else
return(hypot(x,y));
}
// Gaussian function (centred at the origin and ignoring the factor of 1/(s*sqrt(2*PI)) )
double Gaussian(double x, double s)
{
return(exp((-x*x)/(2*s*s)));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -