📄 global.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
// track the edges in the EdgeIntensity array, starting at points that exceed
// the "high" threshold, and continuing to track as long as point values
// don't duck below the "low" threshold (yes, it's hysteresis...I'm sure
// that hyster means "womb" (as in hysterical), but I don't know what
// it's doing in a common engineering term)
///////////////////////////////////////////////////////////////////////////////
void ThresholdingTracker(int high, int low, int Width, int Height, uchar *Img, uchar *EdgeIntensity, uchar *EdgeDir)
///////////////////////////////////////////////////////////////////////////////
// high,low ---- threshold values
// Width,Height ---- picture size
// Img ---- o/p pic array
// EdgeIntensity ---- gradient magnitude array
// EdgeDir ---- gradient direction array
///////////////////////////////////////////////////////////////////////////////
{
int i,j; /* counters */
int ImgSize; /* picture area */
// clear data array before tracking
ImgSize = Width * Height;
for (i = 0; i < ImgSize; ++i) Img[i]=0;
// threshold image with hysteresis: follow from each strong edge point
for (i=0;i<Width;++i) {
for (j=0;j<Height;++j)
if (EdgeIntensity[i+Width*j]>=high)
follow(i,j,low,Width,Height,Img,EdgeIntensity,EdgeDir);
}
}
// follow a connected edge
int follow(int i, int j, int low, int Width, int Height, uchar *Img, uchar *EdgeIntensity, uchar *EdgeDir)
///////////////////////////////////////////////////////////////////////////////
// i,j ----start point
// low ---- lower threshold value
// Width,Height ---- picture dimensions
// Img ---- o/p pic array
// EdgeIntensity ---- gradient magnitude array
// EdgeDir ---- gradient direction array
///////////////////////////////////////////////////////////////////////////////
{
int k,l; /* counters */
int i_plus_1,i_minus_1,j_plus_1,j_minus_1;
long index,kindex;
char break_flag;
i_plus_1=i+1;
i_minus_1=i-1;
j_plus_1=j+1;
j_minus_1=j-1;
index=i+j*Width;
if (j_plus_1>=Height) j_plus_1=Height-1;
if (j_minus_1<0) j_minus_1=0;
if (i_plus_1>=Width) i_plus_1=Width-1;
if (i_minus_1<0) i_minus_1=0;
if (!Img[index]) {
// current point must be added to the list of tracked points
Img[index]=EdgeIntensity[index];
// now we can check immediately adjacent points to see if they too could be added to the track
break_flag=0;
for (k=i_minus_1;k<=i_plus_1;k++) {
for(l=j_minus_1;l<=j_plus_1;++l) {
kindex=k+l*Width;
if (!(l==j && k==i) && EdgeIntensity[kindex]>=low) {
/* && abs(abs(EdgeDir[index]-EdgeDir[kindex])-128)>120*/
if (follow(k,l,low,Width,Height,Img,EdgeIntensity,EdgeDir)) {
break_flag=1;
break;
}
}
}
if (break_flag) break;
}
return(1);
}
else return(0);
}
bool RGB2HSI(BYTE R, BYTE G, BYTE B, WORD& H, float& S, float& I)
{
float temp;
double pi = 3.14159265;
double t = sqrt( 3 );
temp = float (0.5 * ((R - G) + (R - B)) ) / ( (R-G)*(R-G) + (R-B) * (G-B));
I = float(( R + G + B) / t);
S = float(1 - 3.0 * min(R, min(G, B)) / (float)(R + G + B));
H = (WORD) ( (G >= B) ? (acos(temp) * 180 / pi) : (360 - acos(temp) * 180 / pi));
if(H >= 0 && H <= 360)
return true;
else
return false;
}
BOOL RGB2YIQ(BYTE R, BYTE G, BYTE B, BYTE & Y, float & I, float & Q)
{
Y = BYTE( 0.299 * R + 0.587 * G + 0.114 * B );
I = float(0.596 * R - 0.274 * G - 0.322 * B);
Q = float(0.211 * R - 0.523 * G + 0.312 * B);
return TRUE;
}
BYTE RGB2I(BYTE R, BYTE G, BYTE B)
{
float I;
I = float(0.596 * R - 0.274 * G - 0.322 * B);
return BYTE(I);
}
BOOL RGB2Fai(BYTE R, BYTE G, BYTE B, int& Fai)
{
double t;
double u, v;
double degree=57.2957795;//180 / 3.1415926=57.2957795
u = -0.147 * R - 0.289 * G + 0.436 * B;
v = 0.615 * R - 0.515 * G - 0.100 * B;
if(u >= 0)
{
if( v < 0 )
t = atan( v / u ) + 6.2831853;
else
t = atan( v / u );
}
else
t = atan( v / u ) + 3.1415926;
t *= degree;//( 180 / 3.1415926 );57.2957795
Fai = int( t );
if(Fai >= 0 && Fai <= 360 )
return TRUE;
else
return FALSE;
}
//void RGB2HSV(float R,float G,float B,float H,float S,float V)
float RGB2HSV(BYTE R,BYTE G,BYTE B,BOOL flag)
{
float MaxValue,MinValue,diff,Rdist,Gdist,Bdist;
float H,S, V;
MaxValue=MAX3(R,G,B);//求R,G,B最大值
MinValue=MIN3(R,G,B);//求R,G,B最小值
diff=MaxValue-MinValue;
V=MaxValue;
if(MaxValue!=0)
S=diff/MaxValue;
else
S=0;
if(S==0)
H=720;
else
{
Rdist=(MaxValue-R)/diff;
Gdist=(MaxValue-G)/diff;
Bdist=(MaxValue-B)/diff;
if(R==MaxValue)
H=Bdist-Gdist;
else if(G==MaxValue)
H=2+Rdist-Bdist;
else if(B==MaxValue)
H=4+Gdist-Rdist;
H*=60;
if(H<0)
H+=360;
}
if(flag)
return H;
else
return S;
}
////zhm's FindMaxPosition///////////////////////
int FindMaxPosition(int *Data,int Size)
{
int* ArrayData=Data;
int ArraySize=Size;
int Max;
int Position;
Position=0;
Max=0;
for(int i=0;i<ArraySize;i++)
{
if(ArrayData[i]>Max)
{
Max=ArrayData[i];
Position=i;
}
}
return Position;
}
int RGB2Fai(BYTE R, BYTE G, BYTE B)
{
int Fai;
double t;
double u, v;
u = -0.147 * R - 0.289 * G + 0.436 * B;
v = 0.615 * R - 0.515 * G - 0.100 * B;
if(u >= 0)
{
if( v < 0 )
t = atan( v / u ) + 6.2831853;
else
t = atan( v / u );
}
else
t = atan( v / u ) + 3.1415926;
t *= ( 180 / 3.1415926 );
Fai = int( t );
return Fai;
}
void global_DoRotation(BYTE * inImg,BYTE* outImg,int outImgWidth,int outImgHeight,int rx,int ry,int rsize,int rangle)
{
//double cosine=global_TriangleIndex[2*rangle];
//double sine=global_TriangleIndex[2*rangle+1];
double rlinex,rliney;
//int rlinex,rliney;
double cofX,cofY;
double FTmp;
int x1;
double pi = 3.1415926535;
double alpha;
alpha=rangle*pi/180;
double cosine=cos(alpha);
double sine=sin(alpha);
int m_nImageHeight=outImgHeight;
int m_nImageWidth =outImgWidth;
for(int liney=0;liney<m_nImageHeight;liney++)
for(int linex=0;linex<m_nImageWidth;linex++)
{
if(linex>=rx-rsize&&linex<=rx+rsize&&liney>=ry-rsize&&liney<=ry+rsize)
{
rlinex=((linex-rx)*cosine+(liney-ry)*sine)+rx;
rliney=((liney-ry)*cosine-(linex-rx)*sine)+ry;
if(rlinex>=0&&rlinex<m_nImageWidth&&rliney>=0&&rliney<m_nImageHeight)
{
cofX=rlinex-int(rlinex);
cofY=rliney-int(rliney);
//outImg[liney*m_nImageWidth+linex]
//=inImg[int(rliney)*m_nImageWidth+int(rlinex)];
//内插值算法 by ShiGuang Shan
x1 = ((int)rliney) * m_nImageWidth + (int)rlinex;
if(x1>0&&x1 + m_nImageWidth<m_nImageWidth*m_nImageHeight)
{
FTmp = (1-cofX) * (double)inImg[x1] + cofX * (double)inImg[x1 + 1];
FTmp = (1-cofY) * FTmp + cofY * ((1-cofX) * (double)inImg[x1 + m_nImageWidth] + cofX * (double)inImg[x1 + m_nImageWidth + 1]);
outImg[liney*m_nImageWidth+linex]=BYTE (FTmp + 0.5);
}
else
outImg[liney*m_nImageWidth+linex]=inImg[x1];
}
else
outImg[liney*m_nImageWidth+linex]=0;
}
else
outImg[liney*m_nImageWidth+linex]
=inImg[liney*m_nImageWidth+linex];
}
}
void global_DoRotation2(BYTE * inImg,int inImgWidth,int inImgHeight,BYTE* outImg,int outImgWidth,int outImgHeight,int rx,int ry,int rsize,int rangle)
{
//double cosine=global_TriangleIndex[2*rangle];
//double sine=global_TriangleIndex[2*rangle+1];
double rlinex,rliney;
//int rlinex,rliney;
double cofX,cofY;
double FTmp;
int x1;
double pi = 3.1415926535;
double alpha;
alpha=rangle*pi/180;
double cosine=cos(alpha);
double sine=sin(alpha);
int m_nImageHeight=outImgHeight;
int m_nImageWidth =outImgWidth;
for(int liney=0;liney<m_nImageHeight;liney++)
for(int linex=0;linex<m_nImageWidth;linex++)
{
if(linex>=rx-rsize&&linex<=rx+rsize&&liney>=ry-rsize&&liney<=ry+rsize)
{
rlinex=((linex-rx)*cosine+(liney-ry)*sine)+rx;
rliney=((liney-ry)*cosine-(linex-rx)*sine)+ry;
if(rlinex>=0&&rlinex<m_nImageWidth&&rliney>=0&&rliney<m_nImageHeight)
{
cofX=rlinex-int(rlinex);
cofY=rliney-int(rliney);
//outImg[liney*m_nImageWidth+linex]
//=inImg[int(rliney)*m_nImageWidth+int(rlinex)];
//内插值算法 by ShiGuang Shan
x1 = ((int)rliney) * inImgWidth + (int)rlinex;
if(x1>0&&x1 + inImgWidth<inImgWidth*inImgHeight)
{
FTmp = (1-cofX) * (double)inImg[x1] + cofX * (double)inImg[x1 + 1];
FTmp = (1-cofY) * FTmp + cofY * ((1-cofX) * (double)inImg[x1 + inImgWidth] + cofX * (double)inImg[x1 + inImgWidth + 1]);
outImg[liney*m_nImageWidth+linex]=BYTE (FTmp + 0.5);
}
else
outImg[liney*m_nImageWidth+linex]=inImg[x1];
}
else
outImg[liney*m_nImageWidth+linex]=0;
}
else
outImg[liney*m_nImageWidth+linex]
=inImg[liney*inImgWidth+linex];
}
}
void global_DoRotation3(BYTE * inImg,int inImgWidth,int inImgHeight,BYTE* outImg,int outImgWidth,int outImgHeight,int rx,int ry,int rsize,int rangle)
{
double rlinex,rliney;
double cofX,cofY,FTmp;
int x1;
double pi = 3.1415926535;
double alpha;
alpha=rangle*pi/180;
double cosine=cos(alpha);
double sine=sin(alpha);
int m_nImageHeight=outImgHeight;
int m_nImageWidth =outImgWidth;
int yLiney=0;
//yLiney=(liney+9)*m_nImageWidth;
for(int liney=-9;liney<=9;liney++)
{
for(int linex=-9;linex<=9;linex++)
{
rlinex=linex*cosine+liney*sine+9;
rliney=-linex*sine +liney*cosine+9;
cofX=rlinex-int(rlinex);
cofY=rliney-int(rliney);
x1=int(rliney+ry-rsize)*inImgWidth+int(rlinex+rx-rsize);
if(x1>0&&x1 + inImgWidth<inImgWidth*inImgHeight)
{
FTmp=(1-cofX)*(double)inImg[x1]+cofX*(double)inImg[x1+1];
FTmp=(1-cofY)*FTmp+cofY*((1-cofX)*(double)inImg[x1+inImgWidth]+cofX*(double)inImg[x1+inImgWidth+1]);
//outImg[(liney+9)*m_nImageWidth+(linex+9)]=BYTE (FTmp + 0.5);
outImg[yLiney+(linex+9)]=BYTE (FTmp + 0.5);
}
else
//outImg[(liney+9)*m_nImageWidth+(linex+9)]=inImg[x1];
outImg[yLiney+(linex+9)]=inImg[x1];
}
yLiney+=m_nImageWidth;
}
}
double arctg(double x,double y)
{
double angle;
double degree=57.2957795;//57.2957795=180/3.1415926;
if(x>=0)
{
if(y<0)
angle=atan(y/x)+6.2831853;
else
angle=atan(y/x);
}
else
angle=atan(y/x)+3.1415926;
angle*=degree;
return angle;
}
void gConvert(BYTE *InData,BYTE *OutData,int FaiMin,int FaiMax,int fIMin,int fIMax,DWORD dwSize)
{
int Fai;
BYTE R,G,B;
double fI;
//float fI,fQ; BYTE fY;
for(DWORD l = 0; l < dwSize; l++)
{
B = *InData++;
G = *InData++;
R = *InData++;
RGB2Fai(R, G, B, Fai);
fI = 0.596 * R - 0.274 * G - 0.322 * B;
if((Fai>=FaiMin)&&(Fai<=FaiMax)
&&(fI>=fIMin)&&(fI<=fIMax))
*OutData++ = 255;
else
*OutData++ = 0;
}
}
//////////////////////////////////////////////
////Function:gXPosAndMu ////////////////////
////To calculate the Mean and Mu of XData/////
////Authour:Zhang Hongming////////////////////
////Date :2000.8,15 ////////////////////
//////////////////////////////////////////////
CPoint gXPosAndMu(int *XData,int XSize)
{
CPoint rtnPoint=CPoint(0,0);
int XMass,XTotal,XPos,XMu;
XMass=0;
XTotal=0;
XPos=0;
XMu=0;
for(int i=0;i<XSize;i++)
{
XMass+=XData[i];
XTotal+=XData[i]*i;
}
if(XMass>0)
XPos=int(XTotal/(float)XMass);
else return rtnPoint;
for(i=0;i<XSize;i++)
{
XMu+=XData[i]*(i-XPos)*(i-XPos);
}
XMu=int(sqrt((XMu/(float)XMass)));
rtnPoint=CPoint(XPos,XMu);
return rtnPoint;
}
//////////////////////////////////////////////
////Function:gOneDimensionErrosion////////////
////To smooth the curve:Xdata by Errosion/////
////Authour:Zhang Hongming////////////////////
////Date :2000.8,15 ////////////////////
//////////////////////////////////////////////
void gOneDimensionErrosion(int *XData,int XSize)
{
if(XSize<=1)
return;
int i;
int * tempData=new int[XSize];
for(i=0;i<XSize;i++)
tempData[i]=XData[i];
int min_value;
// XData[0]=MIN(tempData[0],tempData[1]);
for(i=1;i<=XSize-2;i++)
{
min_value = 1000;
for(int j=i-1;j<=i+1;j++)
{
if(min_value > tempData[j])
min_value = tempData[j];
}
XData[i]=min_value;
}
// XData[XSize-1]=MIN(tempData[XSize-1],tempData[XSize-2]);
delete tempData;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -