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

📄 videopro.cpp

📁 基于视觉的道路识别技术的智能小车导航源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	  }
	}//else end


  //注意坐标系
   	
    MidPoint=line[int(MaxValue1.Value/2)];
	int g,p;
	int lenx,leny;
	   g=10;
	//按列来检测,距离g=x/sin(theta)
    if(MaxValue1.AngleNumber>=45 && MaxValue1.AngleNumber<=135)
	{
	   
	   for(p=int(MaxValue1.Value/2);p>1;p--)
	   {
	       lenx=(line[p].x-line[p-1].x)/sintab[MaxValue1.AngleNumber];
		   if ( lenx<g )
                StartPoint=line[p-1];
	      else
		       break;
	   }
	    for(p=int(MaxValue1.Value/2);p<MaxValue1.Value-1;p++)
		{
	       lenx=(line[p+1].x-line[p].x)/sintab[MaxValue1.AngleNumber];
			if (lenx<g)
                 EndPoint=line[p+1];
	       else
		       break;
		}
	}
	else//按行来检测,距离g=y/cos(theta)
	{
	   
	    for(p=int(MaxValue1.Value/2);p>1;p--)
		{
	         leny=(line[p].y-line[p-1].y)/fabs(costab[MaxValue1.AngleNumber]);
			if ( leny<g )
                StartPoint=line[p-1];
	      else
		       break;
		}
	    for(p=int(MaxValue1.Value/2);p<MaxValue1.Value-1;p++)
		{
	       leny=(line[p+1].y-line[p].y)/fabs(costab[MaxValue1.AngleNumber]);
			if (leny<g)
                 EndPoint=line[p+1];
	       else
		       break;
		}
	}
    m_StartPoint=StartPoint;
	 m_EndPoint=EndPoint;

    delete[]line;
    GlobalUnlock(hbuf);
	GlobalFree(hbuf);
	GlobalUnlock(hDistAlpha);
	GlobalFree(hDistAlpha);
	return TRUE;


}

void CVideoPro::GetCoreRegion(LPBYTE lpDIBBits, int lHeight, int lWidth, LUV *luv)
{
   WINDOW w;
   RGB rgb;
   int i,j;
   w.LeftX=int(0.4*lWidth);
   w.BottomY=int(0.1*lHeight);
   w.RightX=int(0.5*lWidth);
   w.TopY=int(0.3*lHeight);
   double SumL,SumU,SumV;
   SumL=SumU=SumV=0;
	LUV TempLuv;
	for (i = w.BottomY; i < w.TopY; i ++)
	{
		for (j = w.LeftX; j <w.RightX; j ++)
		{
			// 获取各颜色分量
			unsigned char  B= *((unsigned char *)lpDIBBits + 3*lWidth * i + 3*j);
			
			unsigned char G = *((unsigned char *)lpDIBBits + 3*lWidth* i+ 3*j+1);
			
			unsigned char R = *((unsigned char *)lpDIBBits + 3*lWidth* i + 3*j+2);
			rgb.r=R;
			rgb.g=G;
			rgb.b=B;
            RgbToLuv(&rgb,&TempLuv);
		    SumL=SumL+TempLuv.l;
            SumU=SumU+TempLuv.u;
			SumV=SumV+TempLuv.v;
		}
	}
 luv->l=(double)SumL/double(( w.TopY-w.BottomY)*(w.RightX-w.LeftX));
 luv->u=(double)SumU/double(( w.TopY-w.BottomY)*(w.RightX-w.LeftX));
 luv->v=(double)SumV/double(( w.TopY-w.BottomY)*(w.RightX-w.LeftX));
}


//水平边缘判断,是否为障碍物与地面的交线
BOOL CVideoPro::HorizonEdgeJudge(LPBYTE lpDIBBits, LUV CoreLuv, int lHeight, int lWidth, int row, int col, int Len)
{
int i,k;
k=2*Len;
int sumUp,sumDown;
RGB rgb;
LUV luv; 
double dist;
sumUp=sumDown=0;
  for (i = 0; i <k; i++)
	{
		unsigned char B =*((unsigned char *)lpDIBBits+(row+i-Len)*3*lWidth+3*col);
		unsigned char G =*((unsigned char *)lpDIBBits+(row+i-Len)*3*lWidth+3*col+1);
		unsigned char R =*((unsigned char *)lpDIBBits+(row+i-Len)*3*lWidth+3*col+2);
		rgb.r=R;
        rgb.g=G;
		rgb.b=B;
		double l0,u0,v0,rp;
		l0=CoreLuv.l;
		u0=CoreLuv.u;
		v0=CoreLuv.v;
        RgbToLuv(&rgb,&luv);
		rp=sqrt((luv.l-l0)*(luv.l-l0)+(luv.u-u0)*(luv.u-u0)+(luv.v-v0)*(luv.v-v0));
		dist=15.0;
		if(i<Len && rp<dist)sumDown++;
		if(i>Len && rp<dist)sumUp++;
  }
       
  if((sumDown-sumUp)>0)
	  return TRUE;
  else
	  return FALSE;
}

BOOL CVideoPro::ToGray(LPBYTE lpBytes, int lHeight, int lWidth, WINDOW w)
{
   int i,j;
	// 对各像素进行灰度转换
	// 计算图像每行的字节数
 
    for (i = w.BottomY; i < w.TopY; i ++)
	{
		for (j = w.LeftX; j <w.RightX; j ++)
		{
			// 获取各颜色分量
			unsigned char  B= *((unsigned char *)lpBytes + 3*lWidth * i + 3*j);
			
			unsigned char G = *((unsigned char *)lpBytes + 3*lWidth* i+ 3*j+1);
			
			unsigned char R = *((unsigned char *)lpBytes + 3*lWidth* i + 3*j+2);

			// 计算灰度值
			unsigned char Y = (77 * R + 150 * G + 29 * B) / 256;
          //  unsigned char U = 128+(-44 * R -87* G + 131* B)/256 ; 
		 //   unsigned char V = 128+(131 * R - 110 * G -21 * B)/256 ;
			// 回写灰度值
			*((unsigned char *)lpBytes + 3*lWidth* i + 3*j) = Y;
	    	*((unsigned char *)lpBytes + 3*lWidth* i+ 3*j+1) = Y;
			*((unsigned char *)lpBytes + 3*lWidth* i+ 3*j+2) = Y;
		}
	}
 return TRUE;
}





BOOL CVideoPro::RapidSobel(LPBYTE lpDIBBits, int lHeight, int lWidth)
{
      int x,y;
	  double fx,fy,a1,a2,a;

      BYTE *pTempImage=new BYTE[lWidth*lHeight*3];
	  memcpy(pTempImage,lpDIBBits,lWidth*lHeight*3);

	  for(y=1;y<lHeight-1;y++)
	  {
		  for(x=1;x<lWidth-1;x++)
		  {
			 
			  fx=  lpDIBBits[(x-1)*3+3*(y+1)*lWidth]
				  +2*lpDIBBits[x*3+3*(y+1)*lWidth]
				  +lpDIBBits[(x+1)*3+3*(y+1)*lWidth]
				  -lpDIBBits[(x-1)*3+3*(y-1)*lWidth]
				  -2*lpDIBBits[x*3+3*(y-1)*lWidth]
				  -lpDIBBits[(x+1)*3+3*(y-1)*lWidth];
			  fy=  lpDIBBits[(x-1)*3+3*(y-1)*lWidth]
				  +2*lpDIBBits[(x-1)*3+3*y*lWidth]
				  +lpDIBBits[(x-1)*3+3*(y+1)*lWidth]
				  -lpDIBBits[(x+1)*3+3*(y-1)*lWidth]
				  -2*lpDIBBits[(x+1)*3+3*y*lWidth]
				  -lpDIBBits[(x+1)*3+3*(y+1)*lWidth];
			 //a=fx>0?fx:-fx+fy>0?fy:-fy;
			  a1=fx>0?fx:-fx;
			  a2=fy>0?fy:-fy;
			  a=a1>a2?a1:a2;
			 // a=fx>fy?fx:fy;
			  pTempImage[3*y*lWidth+3*x]=
			  pTempImage[3*y*lWidth+3*x+1]=
			  pTempImage[3*y*lWidth+3*x+2]=BYTE(a);
			  //a>255?255:a;
				
		  
		  }
	  }
      memcpy(lpDIBBits,pTempImage,lWidth*lHeight*3);
	  delete []pTempImage;
	  pTempImage=NULL;
	  return TRUE;
}

BOOL CVideoPro::RapidSobel(LPBYTE lpDIBBits, int *lpAngleData, int lHeight, int lWidth)
{
     int x,y;
	  double fx,fy,a1,a2,a,angle,t;
      double tan1,tan2;
      BYTE *pTempImage=new BYTE[lWidth*lHeight*3];

	  for(y=1;y<lHeight-1;y++)
	  {
		  for(x=1;x<lWidth-1;x++)
		  {
			 
			  fx=  lpDIBBits[(x-1)*3+3*(y+1)*lWidth]
				  +2*lpDIBBits[x*3+3*(y+1)*lWidth]
				  +lpDIBBits[(x+1)*3+3*(y+1)*lWidth]
				  -lpDIBBits[(x-1)*3+3*(y-1)*lWidth]
				  -2*lpDIBBits[x*3+3*(y-1)*lWidth]
				  -lpDIBBits[(x+1)*3+3*(y-1)*lWidth];
			  fy=  lpDIBBits[(x-1)*3+3*(y-1)*lWidth]
				  +2*lpDIBBits[(x-1)*3+3*y*lWidth]
				  +lpDIBBits[(x-1)*3+3*(y+1)*lWidth]
				  -lpDIBBits[(x+1)*3+3*(y-1)*lWidth]
				  -2*lpDIBBits[(x+1)*3+3*y*lWidth]
				  -lpDIBBits[(x+1)*3+3*(y+1)*lWidth];
			 
			  //fx=1.0;
             // fy=-1.732;
			  a1=fx>0?fx:-fx;
			  a2=fy>0?fy:-fy;

			 // arctan(x) = x - x3/3 + x5/5 - x7/7 + .... (2)
			  t=a1>a2?(a2/a1):(a1/a2);//abs(t)<1
			  tan1=t-t*t*t/3+t*t*t*t*t/5-t*t*t*t*t*t*t/7;
              if(fx/fy>0)
			  angle=(a1>a2)?tan1:(PI/2-tan1);
			  else
			  {
			   angle=(a1>a2)?(PI-tan1):(PI-(PI/2-tan1));
			  }

			 // angle=atan2(a2,a1)>0?(atan2(a2,a1)*180/PI):(180+atan2(a2,a1)*180/PI);
              lpAngleData[y*lWidth+x]=int(angle*180/PI);
			  a=a1>a2?a1:a2;
			 // a=fx>fy?fx:fy;
			  pTempImage[3*y*lWidth+3*x]=
			  pTempImage[3*y*lWidth+3*x+1]=
			  pTempImage[3*y*lWidth+3*x+2]=(BYTE)a;
			  //a>255?255:a;
				
		  
		  }
	  }
      memcpy(lpDIBBits,pTempImage,lWidth*lHeight*3);
	  delete []pTempImage;
	  pTempImage=NULL;
      
     return TRUE;
}

BOOL CVideoPro::NEWHough(LPBYTE lpDIBBits, int *lpAngleData, int lHeight, int lWidth, WINDOW w)
{
   BYTE *lpSrc;
    MaxValue MaxValue1;
    int iMaxAngleNumber;
    int iDist;
    int step_distance=1;//步进距离
    double step_angle=PI/180;//步进角
    //循环变量
    int i,k,m;
	long s;
	int x;
    int y;
	double sintab[180],costab[180];
	for(x=0;x<180;x++)
	{
	  sintab[x]=sin(x*PI/180);
	  costab[x]=cos(x*PI/180);
	}
    //存储变换域中的两个最大值
    //计算变换域的尺寸
    m = (int) (sqrt(lWidth*lWidth + lHeight*lHeight)/step_distance);
    //角度从0-180,每格step_angle 度
    iMaxAngleNumber = int(PI/step_angle);
	int *buf,**lpTransArea;
	HGLOBAL    hbuf,hDistAlpha;

 	//分配内存用来处理数据
	if(( hbuf=GlobalAlloc(GHND,2*m*iMaxAngleNumber* sizeof(int)))==NULL){
		//MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;
	}
	buf=(int *)GlobalLock(hbuf);
	//分配内存用来处理数据
	if(( hDistAlpha=GlobalAlloc(GHND,2*m* sizeof(int)))==NULL){
		//MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;
	}
    
    lpTransArea=(int **)GlobalLock(hDistAlpha);
    
	for(i=0;i<2*m;i++)
	{
	  lpTransArea[i]=buf+i*180;//置每行的首地址,每行180度
	  memset(lpTransArea[i],0,180);//计数单元初始化为零
	}
    
   	// 计算图像每行的字节数
	LONG lLineBytes = 3*lWidth  ;
	int ang;
	int count=0;
	
 	for(y =w.BottomY;y<w.TopY;y++) 
	 {
		for(x =w.LeftX;x<w.RightX;x++)
		{

		// 指向源图像第j行,第i个象素的指针			
		 lpSrc = (BYTE *)(lpDIBBits + lLineBytes * y + 3*x);
		//如果是白点,则在变换域的对应各点上加1
    	 if( *lpSrc==255)
			{		//注意步长
			 ang=lpAngleData[lWidth * y +x];
	      if(	ang<=w.MaxAngle && ang>=w.MinAngle)
		   {
			 for(k=w.MinAngle; k<w.MaxAngle;k++)
			   {   //计算距离:
		         s =(long)(x*costab[k]+y*sintab[k]);
				//变换域的对应点上加1
				if(s>=0)
					lpTransArea[s][k]++;
				else
                   // lpTransArea[int(fabs(s))+m][k]++;
                      lpTransArea[int(s+2*m)][k]++;
			   }
		   }
			 
		     }
		}
	}
		
   //找到变换域中的最大值点 && fabs(k-90)>5
MaxValue1.Value=0;
     //找到第一个最大值点
	for (iDist=0; iDist<2*m;iDist++)
	{
	  for(k=w.MinAngle; k<w.MaxAngle;k++)
		{
		  if(lpTransArea[iDist][k]>MaxValue1.Value)
		   {
		     MaxValue1.Value = lpTransArea[iDist][k];
			 
                  MaxValue1.Dist = iDist;
			
			 
			 MaxValue1.AngleNumber = k;
			 
		   }

		}
	}

                m_HoughPara=MaxValue1;
   


	int tt;
	int cc=0;
   // XIANDUAN StartPoint,EndPoint,BufPoint;
	//XIANDUAN* line=new XIANDUAN[MaxValue1.Value];
	int line[288];
	memset(line,0,sizeof(line));
  for(y =w.BottomY;y<w.TopY;y++) 
	 {
		for(x =w.LeftX;x<w.RightX;x++)
		{

		// 指向源图像第j行,第i个象素的指针fabs			
		  int temp=(long)(x*costab[MaxValue1.AngleNumber]+y*sintab[MaxValue1.AngleNumber] ) ;
          if(temp<0) 
			  //tt=int(m+fabs(temp));
               tt=int(2*m+temp);
			  else
			   tt=temp;
//
		  if( MaxValue1.Dist==tt &&( *(lpDIBBits + lLineBytes * y +3*x)==255) )
      		{  
				*(lpDIBBits + lLineBytes * y +3*x)=0;
			    *(lpDIBBits + lLineBytes * y +3*x+1)=255;
			    *(lpDIBBits + lLineBytes * y +3*x+2)=0;
			    line[x]=1;
			  
			}

		/*  else
            {  
				*(lpDIBBits + lLineBytes * y +3*x)=0;
			   *(lpDIBBits + lLineBytes * y +3*x+1)=0;
			    *(lpDIBBits + lLineBytes * y +3*x+2)=0;
			}
		 */ 

		 }
	}
   	
/*			
  int tc=0;
  
  do
  {
   	  //if ( (line[i]-line[0])>=i && (line[i]-line[0])<=i+3 )
	  do
	  {
       if(line[i]==0)
		   i++;
	   tc=i;
	   else
		   break;
		       
	  }while(i<288 )
    StartPoint.x=line[tc];
	  do
	  {
       i=tc;
	   if(line[i]==1)
	   {
		   i++;
	   }

	  }

       
	  // break;
	  }
	  tc++;
  }
	*/
    GlobalUnlock(hbuf);
	GlobalFree(hbuf);
	GlobalUnlock(hDistAlpha);
	GlobalFree(hDistAlpha);
	

// 释放内存
//	delete[] lpTransArea;
return TRUE;
}

BOOL CVideoPro::InteEqualize(LPBYTE lpBytes, int lHeight, int lWidth)
{
  int i,j;
	int* pHistogram=new int[256];
	memset(pHistogram, 0, 256);
	unsigned char   *pTemp;
	int  x, y;
	// 灰度映射表
	BYTE bMap[256];
	//memset(bMap,0,256);
	for(i = 0; i < 256; i++)
	{
		bMap[i] = 0;
	}
 
    for (i = 0; i < lHeight; i ++)
	{
		for (j = 0; j < lWidth; j ++)
		{
			// 获取各颜色分量
			unsigned char  B= *((unsigned char *)lpBytes + 3*lWidth * i + 3*j);
			
			unsigned char G = *((unsigned char *)lpBytes + 3*lWidth* i+ 3*j+1);
			
			unsigned char R = *((unsigned char *)lpBytes + 3*lWidth* i + 3*j+2);

			// 计算灰度值
			unsigned char Y = (77 * R + 150 * G + 29 * B) / 256;
          //  unsigned char U = 128+(-44 * R -87* G + 131* B)/256 ; 
		 //   unsigned char V = 128+(131 * R - 110 * G -21 * B)/256 ;
			pHistogram[Y]++;	
			// 回写灰度值
			*((unsigned char *)lpBytes + 3*lWidth* i + 3*j) =Y ;
	    	*((unsigned char *)lpBytes + 3*lWidth* i+ 3*j+1) = Y;
			*((unsigned char *)lpBytes + 3*lWidth* i+ 3*j+2) = Y;
		}
	}
	// 计算灰度映射表
	for (i = 0; i < 256; i++)
	{
		// 初始为0
		long lTemp = 0;
		
		for (j = 0; j <= i ; j++)
		{
			lTemp += pHistogram[j];
		}
		
		// 计算对应的新灰度值* 255/lHeight / lWidth
		bMap[i] = (BYTE) (lTemp*255/lHeight / lWidth   );
	}

	delete [] pHistogram;
	for(y = 0; y < lHeight; y++)
	{
		pTemp = lpBytes;
		pTemp += y * 3*lWidth;	//位图数据下一行起始指针
		for(x = 0; x < lWidth; x++)
		{
			long lpSrc = pTemp[3*x];
			// 计算新的灰度值
			pTemp[3*x]=pTemp[3*x+1]=pTemp[3*x+2] = bMap[lpSrc];			
		}
	}
	
 return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -