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

📄 videopro.cpp

📁 基于视觉的道路识别技术的智能小车导航源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			lpDst = (unsigned char *)(lpNewDIBBits + lLineBytes * i + j);

			// 目标图像中的当前点先赋成白色
			*lpDst =0;
			*(lpDst + 1) = 0;
			*(lpDst + 2) = 0;
 
			// 如果源图像中3×3结构元素对应位置有黑点	
			// 则将目标图像中的(0,0)点赋成黑色
			for (m = 0; m < 3; m++)
			{
				for (n = 0; n < 3; n++)
				{
					if (T[m * 3 + n] == 0)
						continue;

					if (*(lpSrc + (1 - m) * lLineBytes +(n - 1) * 3) > 128)
					{
						*lpDst = 255;
						*(lpDst + 1) = 255;
						*(lpDst + 2) = 255;
						break;
					}
				}
			}				
		}
	}
	// 复制腐蚀后的图像
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
    // 释放内存
	LocalUnlock(hNewDIBBits);
	LocalFree(hNewDIBBits);
}

void CVideoPro::RoadDetect(LPBYTE lpDIBBits, int lHeight, int lWidth)
{
   //循环变量
	LONG i;
	LONG j;
	LONG m;
	LONG n;
	struct LINE ln[480];
	int xStart,xEnd;
	// 指向源图像的指针
	LPBYTE	lpSrc;
	// 指向缓存图像的指针
	LPBYTE	lpDst;
	// 指向缓存DIB图像的指针
	LPBYTE	lpNewDIBBits;
	HLOCAL	hNewDIBBits;
	// 计算图像每行的字节数
	LONG lLineBytes = lWidth * 3;
	// 暂时分配内存,以保存新图像
	hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);
	if (hNewDIBBits == NULL)
	{
		// 分配内存失败
		return;
	}
	// 锁定内存
	lpNewDIBBits = (LPBYTE)LocalLock(hNewDIBBits);
	// 初始化新分配的内存,设定初始值为0
	lpDst = (LPBYTE)lpNewDIBBits;
	memset(lpDst, (BYTE)0, lLineBytes * lHeight);
	ln[0].StartX=0;
	ln[0].EndX=640;
	for (i = 1; i < lHeight-50 ; i++)
	{
		xStart=0;xEnd=0;
		do
		{
			xStart++;
			lpSrc = (unsigned char *)(lpDIBBits + lLineBytes * i + 3*xStart);
			if(*lpSrc==0)
            continue;
			else
				break;
		}while(xStart<lWidth-1);
		
		
        // if(xStart<ln[i-1].EndX)
			ln[i].StartX=xStart;
		 //else
		//	 continue;
	
			int temp,temp2;
		temp=xStart;
		do
		{
			temp++;
			lpSrc = (unsigned char *)(lpDIBBits + lLineBytes * i + 3*temp);
			if(*lpSrc==255)
            continue;
			else
				break;
			
		}while(temp<lWidth-1);
         xEnd=temp;
	//	if(xEnd>ln[i-1].StartX)
			ln[i].EndX=xEnd;
	//	else
	//		continue;
	
	}
	
     for (i = 1; i < lHeight-50 ; i++)
	{
		 int x1,x2;
         x1=ln[i].StartX;
		 x2=ln[i].EndX;
		for (j = x1; j < x2; j++)
		{
			
			// 指向目标图像倒数第j行,第i个象素的指针			
			*(unsigned char *)(lpNewDIBBits + lLineBytes * i + 3*j)=255;
			*(unsigned char *)(lpNewDIBBits + lLineBytes * i + 3*j+1)=255;
			*(unsigned char *)(lpNewDIBBits + lLineBytes * i + 3*j+2)=255;
		}
	 }

	 	// 复制腐蚀后的图像
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
	// 释放内存
	LocalUnlock(hNewDIBBits);
	LocalFree(hNewDIBBits);



}



void CVideoPro::GuassLaplacian(LPBYTE lpDIBBits, int lHeight, int lWidth)
{
   // 循环变量
	LONG i;
	LONG j;
	LONG k;
	LONG l;
	
	
	// 计算图像每行的字节数
	LONG lLineBytes = lWidth * 3;

	// 不能用char,也不能用::strcpy()
	unsigned char* m_temp;
	m_temp=new unsigned char [lLineBytes * lHeight];

	// 中间变量
	int v, p_g;

	// 检测模版
	int g[25]={-2,-4,-4,-4,-2,
			   -4, 0, 8, 0,-4,
			   -4, 8,24, 8,-4,
			   -4, 0, 8, 0,-4,
			   -2,-4,-4,-4,-2};

	// 复制图象数据到中间缓存
	for (i = 0; i < lLineBytes * lHeight; i++)
		m_temp[i] = *(lpDIBBits + i);

	// 5X5 模版
	for (i = 0; i < lWidth; i++)		//被处理像素在i列
	{
		for (j = 0; j < lHeight; j++)	//被处理像素在j行
		{
			v= p_g = 0;
	
			for (k = i - 2; k < i + 3; k++)	//5*5模版
			{
				for (l = j - 2; l < j + 3; l++)
				{
					// 防止内存溢出
					if (k >= 0  && l >= 0 && k < lWidth && l < lHeight)
					{
							v += *(lpDIBBits + l * lLineBytes + k * 3) * g[p_g];
							p_g++;
					}
				}
			}
			
			if (v < 0)
				v = 0;
			if(v>255)
				v=255;
			

			m_temp[j * lLineBytes + i * 3] = v;
			m_temp[j * lLineBytes + i * 3 + 1] = v;
			m_temp[j * lLineBytes + i * 3 + 2] =v;
		}
	}

	// 回存处理结果到DIB
	for(i = 0; i < lLineBytes * lHeight; i++)
		*(lpDIBBits + i) = m_temp[i];

	
	// 释放内存
	delete[] m_temp;
}

BOOL CVideoPro::TempSobel(LPBYTE lpDIBBits, int lHeight, int lWidth)
{
    // 模板高度
	int	nTempH;
 // 模板宽度
	int nTempW;
	// 模板系数
	float fTempC;
	// 模板中心元素X坐标
	int nTempXc;
	// 模板中心元素Y坐标
	int nTempYc;
	int nX1=-1, nY1=-1, nX2=-1, nY2=-1;
   // 模板元素数组
//	float aValue[9]={-1.0,0,1.0,-1.414,0,1.414,-1.0,0,1.0};//正边缘90方向算子
      float aValue[9]={0,1,2,-1,0,1,-2,-1,0};//135度方向检测算子
	 // float aValue[9]={1,2,1,0,0,0,-1,-2,-1};
	nTempH=3;
	nTempW=3;
	fTempC=1.0;
	nTempXc=1;
	nTempYc=1;
	//对边界像素不作处理
	if( nX1 < nTempXc ) nX1 = nTempXc;
	if( nY1 < nTempYc ) nY1 = nTempYc;
	if( nX2 < lWidth - nTempW + nTempXc + 1) 
		nX2 = lWidth- nTempW + nTempXc + 1;
	if( nY2 < lHeight - nTempH + nTempYc + 1) 
		nY2 = lHeight - nTempH + nTempYc + 1;
	TemplateOperation(lpDIBBits,aValue, fTempC, 
						 nTempW,  nTempH, nTempXc, nTempYc,
						  nX1,  nY1, 
						 nX2,  nY2,
						lHeight,lWidth );
	return TRUE;
}

void CVideoPro::Threshold(LPBYTE lpDIBBits, int lHeight, int lWidth)
{
   int i,j;
    int nHistogramBuffer[256];
   	GetIntensity(lpDIBBits,lHeight,lWidth,nHistogramBuffer);
	// 计算图像每行的字节数
	LONG lLineBytes = lWidth * 3;
    float Sigma[256];
	float Mean1, Mean2;
	
	//Sigma[256]数组清零
	for( i = 0;i < 256; i++) Sigma[i] = 0.0;
	
	int nLevelLow = 0;
	int nLevelHigh = 0;
	
	//查找最小灰度值
	i = 0;
	while(nLevelLow == 0)
	{
		if( nHistogramBuffer[i] != 0 )
		{
			nLevelLow = i;
		}
		i++;
	}

	//查找最大灰度值
	i = 255;
	while(nLevelHigh == 0)
	{
		if( nHistogramBuffer[i] != 0 )
		{
			nLevelHigh = i;
		}
		i--;
	}
   
	//th循环,小于阈值th的像素归为第一类,大于th的像素归为第二类
	//th=0、1、2、…、nLevel。
	for(int th = nLevelLow; th <= nLevelHigh; th++)   
	{
		long lGrayLow = 0;
		long lGrayHigh = 0;
		long lSumLow = 0;
		long lSumHigh = 0;
		for(i = nLevelLow; i < th; i++)
		{
			lSumLow += nHistogramBuffer[i];
			lGrayLow += i * nHistogramBuffer[i];
		}
		for(i = th; i <= nLevelHigh; i++)
		{
			lSumHigh += nHistogramBuffer[i];
			lGrayHigh += i * nHistogramBuffer[i];
		}
		
		if( lSumLow > 0 )
		{
			Mean1 = (float)lGrayLow / lSumLow;
		}
		else
		{
			Mean1 = 0.0;
		}
		if( lSumHigh > 0)
		{
			Mean2 = (float)lGrayHigh / lSumHigh;
		}
		else
		{
			Mean2 = 0.0;
		}
		
		//计算两类之间的方差
		Sigma[th] = (float)lSumLow * lSumHigh 
			* (Mean1 - Mean2) * (Mean1 - Mean2);
	}
	
	//th循环结束,求方差最大的阈值
	float MaxSigma = Sigma[nLevelLow];
	int Thresh = 0;
	for( i = nLevelLow + 1; i <= nLevelHigh; i++)
	{
		if(MaxSigma < Sigma[i])
		{
			MaxSigma = Sigma[i];
			Thresh = i;
		}
	}
	
	// 对各像素进行灰度转换lHeight, int lWidth
	for (i = 0; i <lHeight; i ++)
	{
		for (j = 0; j < lWidth; j ++)
		{
			unsigned char  Y= *((unsigned char *)lpDIBBits + 3*lWidth * i + 3*j);
			if(Y < Thresh)
			{
			// 回写灰度值
			*((unsigned char *)lpDIBBits + 3*lWidth* i + 3*j) = 0;
	    	*((unsigned char *)lpDIBBits + 3*lWidth* i+ 3*j+1) = 0;
			*((unsigned char *)lpDIBBits + 3*lWidth* i+ 3*j+2) = 0;
			}else
            {
			// 回写灰度值
			*((unsigned char *)lpDIBBits + 3*lWidth* i + 3*j) = 255;
	    	*((unsigned char *)lpDIBBits + 3*lWidth* i+ 3*j+1) = 255;
			*((unsigned char *)lpDIBBits + 3*lWidth* i+ 3*j+2) = 255;
			}
		}
	}
}

void CVideoPro::GetIntensity(LPBYTE lpDIBBits, int lHeight, int lWidth, int *nNs_Y)
{
   // 循环变量
 	LONG i;
 	LONG j;
  	// 变量初始化
 	memset(nNs_Y, 0, sizeof(nNs_Y));
  	// 计算图像每行的字节数
 	LONG lLineBytes = lWidth * 3;

 	// 对各像素进行灰度转换
 	for (i = 0; i <  lHeight; i ++)
 	{
 		for (j = 0; j < lWidth; j ++)
 		{
 			unsigned char Y = *((unsigned char *)lpDIBBits + lLineBytes * i + 3*j);
 		
 		// 灰度统计计数
 			nNs_Y[Y]++;		
 		}
 	}
}

BOOL CVideoPro::Hough(LPBYTE lpBufBits, LPBYTE lpDIBBits/*原图像*/, 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];
	BOOL flag;
	LUV CoreLuv;
	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 count=0;
	GetCoreRegion(lpDIBBits, lHeight, lWidth, &CoreLuv);
 	for(y =w.BottomY;y<w.TopY;y++) 
	 {
		for(x =w.LeftX;x<w.RightX;x++)
		{

		// 指向源图像第j行,第i个象素的指针			
		 lpSrc = (BYTE *)(lpBufBits + lLineBytes * y + 3*x);
		//如果是白点,则在变换域的对应各点上加1
		 
		 flag=HorizonEdgeJudge(lpDIBBits,CoreLuv,\
			               lHeight, lWidth, y, x, 3);
    	 if( (*lpSrc==255)&& flag)
			{		//注意步长
			 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(s+2*m)][k]++;
			 }
		   }
		}
	}
   MaxValue1.Value=0;
     //找到第一个最大值点
	for (iDist=0; iDist<2*m;iDist++)
	{
	  for(k=0; k<iMaxAngleNumber;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;
	POINT StartPoint,EndPoint,MidPoint;
/*	HGLOBAL    hLine;
	//分配内存用来处理数据
	if(( hLine=GlobalAlloc(GHND,MaxValue1.Value* sizeof(int)))==NULL){
		//MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;
	}
	buf=(int *)GlobalLock(hbuf);
*/
	POINT* line=new POINT[MaxValue1.Value];
//	POINT line[26];
	//如果直线为偏水平的,按列,下面按x检测
    if((MaxValue1.AngleNumber>=45) && (MaxValue1.AngleNumber<=135))
	{
      for(x =w.LeftX;x<w.RightX;x++)
	  {
		for(y =w.BottomY;y<w.TopY;y++)
		{
    		 int temp=(int)(x*costab[MaxValue1.AngleNumber]+y*sintab[MaxValue1.AngleNumber] ) ;
            if(temp<0) 
			    tt=(2*m+temp);
			  else
			   tt=temp;
		    if( MaxValue1.Dist==tt &&( lpBufBits[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[cc].x=x;
				line[cc].y=y;
				cc++;
			}
		}
	  }
	}
	else//如果直线为偏竖直的,按行,并且下面按y来检测
	{
	  for(y =w.BottomY;y<w.TopY;y++)
	  {
		for(x =w.LeftX;x<w.RightX;x++)
		{

		  int temp=(int)(x*costab[MaxValue1.AngleNumber]+y*sintab[MaxValue1.AngleNumber] ) ;
          if(temp<0) 
			   tt=(2*m+temp);
			  else
			   tt=temp;
		  if( MaxValue1.Dist==tt &&( *(lpBufBits+ 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[cc].x=x;
				line[cc].y=y;
				cc++;
		  }

		}

⌨️ 快捷键说明

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