⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imageprocessing.cpp

📁 车牌识别及定位
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#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=&cent;
    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 + -