📄 imageprocessing.cpp
字号:
#include <stdafx.h>
#include <windows.h>
#include <math.h>
#include <malloc.h>
#include "resource.h"
#include "BmpTest.h"
#include "BmpTestDoc.h"
/******************************************************************** *
* *
* ro_angle:rotated angle *
* size :the size of the rotated bitmap *
* pav_cent:the rotate centre *
* **********************************************************************/
extern void Sh_Rotate(CBmpTestDoc* pDoc,double ro_angle,double size,POINT *pav_cent)
{
BYTE *lp=pDoc->m_Dib.m_Buffer,*ltemp;
int m,n;
unsigned int a,b,d,j,k,stand=150,Height,Width,BPL,i;
DWORD shift,y_value;
DWORD large;
double rotate,x_value,sinth,costh;
m=pav_cent->x;
n=pav_cent->y;
sinth=sin(-ro_angle);
Height=(int) pDoc->m_Dib.Height;
Width=(int) pDoc->m_Dib.Width;
BPL=(int) pDoc->m_Dib.Bpl;
costh=cos(-ro_angle);
//loritemp 是本地的图像副本总指针,ltemp指向数据区,biSize是BITMAPINFORHEADER的大小为40
ltemp=new BYTE[9600];
//initioalize the new field orign lpbi->biSizeImage
for(j=0;j<9600;j++)
*(ltemp+j)=0;
//if it is the bmppoint then enlage
for(k=0;k<Height;k++)
{
for(i=0;i<=(int)(Width/8);i++)
{
if((i+1)*8<Width)
d=8;
else
d=(unsigned)(Width-i*8);
a=128;
if(d!=0)
{
for(j=0;j<d;j++)
{
//if the bit is equal to 0 it is background
if((*(lp+(LONG)i+(LONG)k*BPL) & a) ==0)
a=a>>1;
else
{
//i is the x coordinate so it is byte
x_value=(float)8*i+(float)j;
rotate=(x_value -m)*(costh)-(sinth) *((float)k-n);
rotate*=(double)110.0/size;
rotate+=(double)160.0;
large=(int)(rotate/8);
shift=(int)rotate-large*8;
b=128;
//shift>=0 it is in the next store,本身他已处于下一单元(i 从零开始)
y_value=(LONG)(((x_value -m)*sinth+costh*((float)k-n))
*110.0/size +(float)120 )*(LONG)(40);
large +=y_value;
b=b>>shift;
if(large < (9600-1))
*(ltemp+large)|= b;
a=a>>1;
}
}
}
}
}
// If the driver did not fill in the biSizeImage field, make one up
pDoc->m_Dib.Width=320;
pDoc->m_Dib.Height=300;
pDoc->m_Dib.Resize(9600);
for(j=0;j<9600;j++)
{
*(pDoc->m_Dib.m_Buffer+j)=*(ltemp+j);
*(pDoc->m_Dib.m_Buffer1+j)=*(ltemp+j);
}
if(lp)
{
delete [] lp;
lp=0;
}
if(ltemp)
{
delete [] ltemp;
ltemp=0;
}
}
/**************************************************************************
* n *
* gcc:the gravity contour centre of the bitmap *
***************************************************************************/
extern BOOL GCC(CBmpTestDoc* pDoc,double *n,POINT *gcc)
{
//1:xnear 2:xfarer 3:ynear 4:yfarer
BYTE *lp=pDoc->m_Dib.m_Buffer;
char name1[2]="1",name2[2]="2",name3[2]="3",name4[2]="4";
int i,k,tempx,xImagecon[2000],BPL,black,white,Height,Width;
unsigned int a=1,d,j,maxx,minx;
DWORD x=0,y=0,centx=0,centy=0,counts=0;//counts represents the conunt of the contour
//cent represent the center_mass while av_cent represent the average center
DISTANCE xdis[50];
PDISTANCE pdis;
//let x repreterative the near and y represertive the far
POINT Imagecon[100],min,max,last,cent,av_cent,*pcent,*pav_cent;
//float distwo;
BOOL maxfind=FALSE,minfind=FALSE,begin=TRUE,equal1,equal2,equal3;
double l,dis,midx,midy,d_centx,d_centy;
Height=(int) pDoc->m_Dib.Height;
Width=(int) pDoc->m_Dib.Width;
BPL=(int) pDoc->m_Dib.Bpl;
pcent=¢
pav_cent=&av_cent;
pdis=xdis;
for(i=0;i<50;i++)
(pdis+i)->number=0;
for(i=0;i<2000;i++)
xImagecon[i]=0;
for(i=0;i<100;i++)
{
Imagecon[i].x=0;
Imagecon[i].y=0;
}
for(k=0;k<Height;k++)
{
for(i=0;i<=(int)((Width)/8);i++)
{
a=255;
if(((*(lp+i+k*BPL)) & a) ==0)
continue;
if((i+1)*8<(Width))
d=8;
else
d=(unsigned)((Width)-i*8);
a=128;
if(d!=0)
{
for(j=0;j<d;j++)
{
//if the bit is equal to 0 it is background
if(((*(lp+i+k*BPL)) & a) ==0)
{ y++;
a=a>>1;}
else
{ x++;
a=a>>1;
centx=(WORD)i*8+j+centx;
centy=(WORD)k+centy;
//分别求出从两个方向的投影点的轮廓
//从x方向求 k为其 坐标
if(xImagecon[k] ==0)
xImagecon[k] =i*8+j;
xImagecon[500+k] =max(xImagecon[500+k],i*8+(int)j);
xImagecon[k] =min(xImagecon[k],i*8+(int)j);
//从y方向求tempx为其坐标
tempx=i*8+j;
if(xImagecon[1000+tempx]==0)
xImagecon[1000+tempx] =k;
xImagecon[1500+tempx] =max(xImagecon[1500+tempx],k);
xImagecon[1000+tempx] =min(xImagecon[1000+tempx],k);
}
}
}
}
}
//图的直方图
black=y;
white=x;
//求重心
d_centx=((double)centx/x);
d_centy=((double) centy/x);
for(k=0;k<4;k++)
{
max.x=0;
max.y=0;
min.x=0;
min.y=0;
j=0;
maxx=0;
begin=TRUE;
maxfind=FALSE;
minfind=FALSE;
for(i=1;i<500;i++)
{
//i 值为其 y方向的值 xImagecon 存的是X方向的最近和最远
if(xImagecon[k*500+i] !=0)
{
if(max.x==0)
{
max.x=xImagecon[k*500+i];
//the first point is a contour point
if(j==0)
{ j++;
if(k<2)
{
Imagecon[k*20+j].x=max.x;
Imagecon[k*20+j].y=i;
j++;
}
else
{
Imagecon[k*20+j].y=max.x;
Imagecon[k*20+j].x=i;
j++;
}
}
}
if(min.x==0) min.x=xImagecon[k*500+i];
if(!minfind || begin)
{
if(min.x>=xImagecon[k*500+i])
{
min.x=xImagecon[k*500+i];
min.y=i;
minx=0;
}
else
{
minx++;
if((minx>=2) && (min.x<=xImagecon[k*500+i]-2) && (min.x<=max.x+2))
{
minfind=TRUE;
begin=FALSE;
}
}
}
if(!maxfind || begin)
{
if(max.x<=xImagecon[k*500+i])
{
max.x=xImagecon[k*500+i];
max.y=i;
maxx=0;
}
else
{
maxx++;
if((maxx>=2) && (max.x>=xImagecon[k*500+i]+2) && (max.x>=min.x+2))
{
maxfind=TRUE;
begin=FALSE;
minfind=FALSE;
}
}
}
last.x=xImagecon[k*500+i];
last.y=i;
if((maxfind && (maxx>=2)) || (minfind && (minx>=2)))
{
if(minfind)
{
if(k==0)
{
Imagecon[k*20+j].x=min.x;
Imagecon[k*20+j].y=min.y;
j++;
}
if(k==2)
{
Imagecon[k*20+j].y=min.x;
Imagecon[k*20+j].x=min.y;
j++;
}
max.x=min.x;
max.y=min.y;
maxfind=FALSE;
}
if(maxfind)
{
if(k==1)
{
Imagecon[k*20+j].x=max.x;
Imagecon[k*20+j].y=max.y;
j++;
}
if(k==3)
{
Imagecon[k*20+j].y=max.x;
Imagecon[k*20+j].x=max.y;
j++;
}
min.x=max.x;
min.y=max.y;
}
*(lp+Imagecon[k*20+j-1].x/8+Imagecon[k*20+j-1].y * BPL/4) ^ 255;
*(lp+Imagecon[k*20+j-1].x/8+Imagecon[k*20+j-1].y * BPL/4) ^ 255;
minx=0;
maxx=0;
}
}
}
Imagecon[k*20].x=j;
if(k<2)
{
Imagecon[k*20+j].x=last.x;
Imagecon[k*20+j].y=last.y;
}
else
{
Imagecon[k*20+j].x=last.y;
Imagecon[k*20+j].y=last.x;
}
}
//去掉相同点
for(i=0;i<4;i++)
{
k=Imagecon[20*i].x;
Imagecon[20*i].x=0;
pav_cent->x =Imagecon[20*i+1].x;
pav_cent->y =Imagecon[20*i+1].y;
last.x=Imagecon[20*i+k].x;
last.y=Imagecon[20*i+k].y;
for(j=0;j<40;j++)
{
if((i==0) && (Imagecon[40+20*(int)(j/20)+2].x<=pav_cent->x) && (Imagecon[40+j].y==pav_cent->y) )
equal1=TRUE;
else
equal1=FALSE;
if((i==2) && (Imagecon[20*(int)(j/20)+2].y<=pav_cent->y) && (Imagecon[j].x==pav_cent->x) )
equal2=TRUE;
else
equal2=FALSE;
tempx=40*(1-(int)(i/2))+j;
if((Imagecon[tempx].x==pav_cent->x) && (Imagecon[tempx].y==pav_cent->y))
equal3=TRUE;
else
equal3=FALSE;
if(equal3 || equal1|| equal2)
{
Imagecon[20*i+1].x=0;
Imagecon[20*i+1].y=0;
}
if ((i==0) && (Imagecon[40+20*(int)(j/20)+2].x<=last.x) &&
(Imagecon[40+j].y==last.y))
equal1=TRUE;
else
equal1=FALSE;
if((i==2) &&(Imagecon[20*(int)(j/20)+2].y<=last.y) && (Imagecon[j].x==last.x))
equal2=TRUE;
else
equal2=FALSE;
tempx=40*(1-i/2)+j;
if((Imagecon[tempx].x==last.x) && (Imagecon[tempx].y==last.y))
equal3=TRUE;
else
equal3=FALSE;
if(equal3 || equal1 || equal2)
{
Imagecon[20*i+k].x=0;
Imagecon[20*i+k].y=0;
}
}
}
//caculate the GCC
for(j=0;j<20;j++)
{
last.x=Imagecon[20+j].x;
last.y=Imagecon[20+j].y;
Imagecon[20+j].x=Imagecon[60+j].x;
Imagecon[20+j].y=Imagecon[60+j].y;
Imagecon[60+j].x=last.x;
Imagecon[60+j].y=last.y;
}
l=0.;
midx=0;
midy=0;
max.x=0;
max.y=0;
for(i=0;i<80;i++)
{
if(Imagecon[i].x !=0)
{
min.x=Imagecon[i].x;
min.y=Imagecon[i].y;
if(max.x==0)
{
//max store the initional value
max.x=min.x;
max.y=min.y;
}
j=i+1;
while((Imagecon[j].x==0) && (j<80))
j++;
if((j>40) && (i<40))
{
// pav_cent store the end of the y direction maxmun value
pav_cent->x=min.x;
pav_cent->y=min.y;
min.x=max.x;
min.y=max.y;
}
last.x=Imagecon[j].x;
last.y=Imagecon[j].y;
if(j==80)
{
last.x=pav_cent->x;
last.y=pav_cent->y;
}
dis=sqrt((double)(min.x-last.x)*(min.x -last.x)+
(double)(min.y-last.y)*(min.y-last.y));
midx =(double)(min.x+last.x)/2 *dis +midx;
midy =(double)(min.y+last.y)/2 *dis +midy;
l+=dis;
i=j-1;
}
}
midx=midx/l;
midy=midy/l;
gcc->x=(int)midx;
gcc->y=(int)midy;
l=0;
for(i=0;i<80;i++)
{
if(Imagecon[i].x !=0)
{
dis=(Imagecon[i].x-midx)*(Imagecon[i].x-midx)+(Imagecon[i].y-midy)*(Imagecon[i].y-midy);
dis=sqrt(dis);
l=max(dis,l);
}
}
*n=l;
return TRUE;
}
/***************************************************************************
* pAnew_mom:the query bitmap's moments *
* n:the size of the bitmap *
* protate :the rotated angle
* the moment name of the calculation below is the same as the maths define *
***************************************************************************/
extern BOOL Contour(CBmpTestDoc* pDoc,double *pAnew_mon,BOOL bmoment,double n,double *protate)
{
//1:xnear 2:xfarer 3:ynear 4:yfarer
BYTE *lp=pDoc->m_Dib.m_Buffer;
char Outtext[300]="",ext1[15]="mom.txt",filename1[30];
int i,k,tempx,black,white,BPL,Height,Width;
unsigned int a=1,d,j;
DWORD x=0,y=0,centx=0,centy=0,counts=0;//counts represents the conunt of the contour
//cent represent the center_mass while av_cent represent the average center
DISTANCE xdis[50];
PDISTANCE pdis;
//let x repreterative the near and y represertive the far
bool maxfind=false,minfind=false,begin=true;
double l,mid,d_centx,d_centy,A1,A2,A3,A4,A5,A6,A7,N,coefient,
u02,u20,u03,u30,u11,u21,u12,a1,a2,a3,a4,a5,a6,a7,
m01,m02,m03,m20,m30,m11,m21,m12;
FILE *ffp;
Height=(int) pDoc->m_Dib.Height;
Width=(int) pDoc->m_Dib.Width;
BPL=(int) pDoc->m_Dib.Bpl;
pdis=xdis;
N=n;
for(i=0;i<50;i++)
(pdis+i)->number=0;
u02=0;u03=0;u20=0;
//求直方图
for(k=0;k<(Height);k++)
{
for(i=0;i<=Width/8;i++)
{
a=255;
if(((int)*(lp+i+k*BPL) & a) ==0)
continue;
if((i+1)*8<Width)
d=8;
else
d=(unsigned)(Width-i*8);
a=128;
if(d!=0)
{
for(j=0;j<d;j++)
{
//if the bit is equal to 0 it is background
if(((int)*(lp+i+k*BPL) & a) ==0)
{
y++;
a=a>>1;
}
else
{
x++;
a=a>>1;
centx=(WORD)i*8+j+centx;
centy=(WORD)k+centy;
}
}
}
}
}
//图的面积=x+y
black=y;
white=x;
//求重心
d_centx=((double)centx/x);
d_centy=((double) centy/x);
//归一化系数
coefient=(double)x*x;
A7=sqrt((double)x);
//A7=sqrt(a1);
mid=coefient*A7;
u11=0;u02=0;u03=0;u20=0;u30=0;u12=0;u21=0;
m11=0;m01=0;m02=0;m03=0;m20=0;m30=0;m12=0;m21=0;
A1=0.;A2=0.;A3=0.;A4=0.;A5=0.;A6=0.;A7=0.;
for(k=0;k<Height;k++)
{
for(i=0;i<=(int)Width/8;i++)
{
a=255;
if((((int)*(lp+i+k*BPL)) & a)==0)
continue;
if((i+1)*8<Width)
d=8;
else
d=(unsigned)(Width-i*8);
a=128;
if(d!=0)
{
for(j=0;j<d;j++)
{
//if the bit is equal to 0 it is background
if((((int)*(lp+i+k*BPL)) & a) ==0)
a=a>>1;
else
{
a=a>>1;
tempx=i*8+j;
a1=((double)k-d_centy)*((double)k-d_centy);
u02+=a1;
a2=a1*(k- d_centy);
u03+=a2;
a3=(tempx- d_centx)*(tempx-d_centx);
u20+=a3;
u30+=a3*(tempx- d_centx);
a4=(tempx-d_centx)*(k-d_centy);
u11+=a4;
a5=a4*(tempx-d_centx);
u21+=a5;
a6=a4*(k-d_centy);
u12+=a6;
}
}
}
}
//to calculate the scale transform
a3=u02/coefient;
A1=A1+a3;
u02=0.;
a3=u20/coefient;
A2=A2+a3;
u20=0.;
a3=u11/coefient;
A3=a3+A3;
u11=0.;
a3=u03/mid;
A4=A4+a3;
u03=0.;
a3=u30/mid;
A5=A5+a3;
u30=0.;
a3=u21/mid;
A6=A6+a3;
u21=0.;
a3=u12/mid;
A7=A7+a3;
u12=0.;
}
u02=A1;
u20=A2;
u11=A3;
u03=A4;
u30=A5;
u21=A6;
u12=A7;
//rotated invariant moment
a1=u02+u20;
a2=(u20-u02)*(u20-u02)+u11*u11*4;
a3=(u30- u12*3)*(u30-u12*3)+(u21*3-u03)*(u21*3-u03);
a4=(u30+u12)*(u30+u12)+(u03+u21)*(u03+u21);
a5=(u30-u12*3)*(u30+u12)*((u30+u12)*(u30+u12)-(u21+u03)*(u21+u03)*3)
+(u21*3-u03)*(u21+u03)*((u30+u12)*(u30+u12)*3-(u21+u03)*(u21+u03));
a6=(u20-u02)*((u30+u12)*(u30+u12)-(u21+u03)*(u21+u03))
+u11*(u30+u12)*(u21+u03)*4;
a7=(u21*3-u03)*(u30+u12)*((u30+u12)*(u30+u12)-(u21+u03)*(u21+u03)*3)
-(u30-u12*3)*(u21+u03)*((u30+u12)*(u30+u12)*3 -(u21+u03)*(u21+u03));
//calculate the rotate angle
u11=2*u11;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -