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

📄 videopro.cpp

📁 基于视觉的道路识别技术的智能小车导航源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		  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;
	POINT* line=new POINT[MaxValue1.Value];
	//如果直线为偏水平的,按列,下面按x检测
    if((MaxValue1.AngleNumber>=45) && (MaxValue1.AngleNumber<=135))
	{
      for(x =w.LeftX;x<w.RightX;x++)
	  {
		for(y =w.BottomY;y<w.TopY;y++)
		{

		// 指向源图像第j行,第i个象素的指针fabs			
		  int temp=(int)(x*costab[MaxValue1.AngleNumber]+y*sintab[MaxValue1.AngleNumber] ) ;
          if(temp<0) 
			  //tt=int(m+fabs(temp));
               tt=(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[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 &&( *(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[cc].x=x;
				line[cc].y=y;
				cc++;
		  }

		}
	  }
	}//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;
		}
	}
	/*
	if(MaxValue1.AngleNumber<90)
	{
    	StartPoint.x=int(MidPoint.x-MaxValue1.Value*sintab[MaxValue1.AngleNumber]/2);
        StartPoint.y=int(MidPoint.y+MaxValue1.Value*costab[MaxValue1.AngleNumber]/2);
		EndPoint.x=int(MidPoint.x+MaxValue1.Value/2*sintab[MaxValue1.AngleNumber]);
        EndPoint.y=int(MidPoint.y-MaxValue1.Value/2*costab[MaxValue1.AngleNumber]);
	}
	else
	{
		StartPoint.x=int(MidPoint.x-MaxValue1.Value*sintab[180-MaxValue1.AngleNumber]/2);
        StartPoint.y=int(MidPoint.y-MaxValue1.Value*costab[180-MaxValue1.AngleNumber]/2);
		EndPoint.x=int(MidPoint.x+MaxValue1.Value/2*sintab[180-MaxValue1.AngleNumber]);
        EndPoint.y=int(MidPoint.y+MaxValue1.Value/2*costab[180-MaxValue1.AngleNumber]);
	}
	*/
	m_StartPoint=StartPoint;
	 m_EndPoint=EndPoint;
	delete[]line;
    line=NULL;
    GlobalUnlock(hbuf);
	GlobalFree(hbuf);
	GlobalUnlock(hDistAlpha);
	GlobalFree(hDistAlpha);
return TRUE;
}

void CVideoPro::Convolution(float *fpData, float *fpKernel, float fCoef,
							int nSize, unsigned char *nResult)

{

	int i;
	float Sum = 0, fResult;

	//计算卷积
	for(i = 0; i < nSize; i++)
	{
		Sum += fpData[i] * fpKernel[i];
	}

	//执行卷积后的结果
	fResult = Sum / fCoef;

	//求绝对值
	fResult = (float)fabs(fResult);
	
	//判断是否超过255
	if(fResult > 255.0 )
	{
		// 直接赋值为255
		fResult = 255.0;
	}
	
	//对卷积结果四舍五入,并转换成unsigned char类型作为最后返回结果
	*nResult = (unsigned char) (fResult + 0.5);			
}
////////////////////////////////////////////////////////////////////////
//BOOL TemplateOperation()   
//----------------------------------------------------------------------
//基本功能:该函数用指定的模板(任意大小)来对图像数据区的数据进行模板操
//			作,参数nTempH指定模板的高度,参数nTempW指定模板的宽度,参数
//			nTempXc和nTempYc指定模板的中心元素坐标,参数fpArray为指定模
//			板元素数组的指针,fCoef指定模板系数。
//----------------------------------------------------------------------
//参数说明:float *fpArray			指向模板数组的指针
//			float fCoef				模板系数
//			int   nTempW			模板的宽度
//			int   nTempH			模板的高度
//			int   nTempXc			模板的中心元素X坐标 ( <= nTempW - 1)
//			int   nTempYc			模板的中心元素Y坐标 ( <= nTempH - 1)
//			unsigned char *pData	图像数据指针
//			int nWidthBytes			图像字节宽度
//			int	  nX1				处理区域左边界		
//			int   nY1				处理区域上边界
//			int	  nX2				处理区域右边界
//			int	  nY2				处理区域下边界
//----------------------------------------------------------------------
//返    回:BOOL
//			成功时返回TRUE,失败时返回FALSE。
//----------------------------------------------------------------------
//注    意:此函数声明为保护型,只能在CVideoPro类中使用。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CVideoPro::TemplateOperation(LPBYTE lpDIBBits,float *fpArray, float fCoef, 
						int nTempW, int nTempH, int nTempXc, int nTempYc,
						 int nX1, int nY1, 
						int nX2, int nY2,
						int nHeight,int nWidth )
{
	
	//定义变量
	unsigned char Data;
	 unsigned char Result1,Result2;

	//定义与图像数据操作有关的变量
	unsigned char *pOldBits, *pNewBits,*pBufBits,
				  *pOldTemp, *pNewTemp,
				  *pNeighborTemp;
	int  x, y, i, j;
	int dwNewSize;
	//原图像数据指针LPBYTE lpDIBBits
	pOldBits = (BYTE*)lpDIBBits;
	HGLOBAL hNewDib,hBufDib;
	//新图像文件大小(以字节为单位)
	dwNewSize = nWidth * nHeight;
	//为新图像分配内存
	hNewDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
	//内存分配失败
	if( hNewDib == NULL )
		return( FALSE );
	//新图像指针
	pNewBits = (unsigned char *) ::GlobalLock( hNewDib );
	if( pNewBits == NULL )
	{
		::GlobalFree( hNewDib );
		return( FALSE );
	}
	//为中转图像分配内存
	hBufDib = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
	//内存分配失败
	if( hBufDib == NULL )
		return( FALSE );
	//中转图像指针
	pBufBits = (unsigned char *) ::GlobalLock( hBufDib );
	if( pBufBits == NULL )
	{
		::GlobalFree( hBufDib );
		return( FALSE );
	}
	//复制图像数据
     for(y = 0; y < nHeight; y++ )
	 {
		 for(x = 0; x < nWidth; x++ )
		 {
			 pBufBits[nWidth*y+x]=lpDIBBits[3*nWidth*y+3*x];

		 }
	 }	


	//定义卷积运算中用的临时数组 2个
	float *pGray = new float [nTempW * nTempH];
	if(pGray == NULL) return( NULL );
	memset(pGray, 0, (nTempW * nTempH) * sizeof(float));
	
	//行位置
	for(y = nY1; y < nY2; y++ )
	{
		//原图像数据指针定位到起始位置
		pOldTemp = pBufBits;
		//原图像数据指针定位到图像数据每行的起始零位置(nHeight -1 - y)
		pOldTemp +=  y* nWidth;
		//原图像数据指针定位到图像数据每行的起始nX1-1位置
		pOldTemp += nX1;
		//新图像数据指针定位到起始位置
		pNewTemp = pNewBits;
		//新图像数据指针定位到图像数据每行的起始零位置(nHeight -1 - y)
		pNewTemp += y * nWidth;
		//新图像数据指针定位到图像数据每行的起始nX1位置
		pNewTemp += nX1;
		
		//列位置
		for(x = nX1; x < nX2; x++)
		{
			//取出原图像nTempW×nTempH邻域内的像素值
			for (i = 0; i < nTempH; i++)
			{
				for (j = 0; j < nTempW; j++)
				{
					//数据指针指向当前像素
					pNeighborTemp = pOldTemp;
					//数据指针指向原图像第y - nTempYc + i行。
					pNeighborTemp += nWidth * (i-nTempYc);
					//第x - nTempXc + j列像素的指针
					pNeighborTemp += (j - nTempXc);
					
					//获取像素值
					Data = *pNeighborTemp;

					pGray[i * nTempW + j] = (float)Data;
				}
			}

			//卷积核尺寸
			int nSize = nTempW * nTempH;
	    //	float fpArray2[9]={1,2,1,0,0,0,-1,-2,-1};
           // float fpArray2[9]={1,1.414,1,0,0,0,-1,-1.414,-1};
		//		float fpArray2[9]={-2,-1,0,-1,0,1,0,1,2};//45度方向算子
			float fpArray2[9]={1,0,-1,2,0,-2,1,0,-1};
			
			////作卷积
			Convolution(pGray, fpArray, fCoef, nSize, &Result1);
			Convolution(pGray, fpArray2, fCoef, nSize, &Result2);
			
			
			if(Result1<Result2)
			Result1=Result2;
    	
			
			//将计算结果赋于新图像
			*pNewTemp = Result1;
			/*
			if(Result1+Result2>255)
             *pNewTemp=255.0;
			else
			*pNewTemp = (Result1+Result2);
			*/
			//新旧图像数据指针加1
			pOldTemp++;
			pNewTemp++;
			
		}
	}
	
	//释放内存
	delete [] pGray;

	//复制图像数据
	//复制图像数据
     for(y = 0; y < nHeight; y++ )
	 {
		 for(x = 0; x < nWidth; x++ )
		 {
			 pOldBits[3*nWidth*y+3*x]=\
			 pOldBits[3*nWidth*y+3*x+1]=\
			 pOldBits[3*nWidth*y+3*x+2]=pNewBits[nWidth*y+x];

		 }
	 }	
	lpDIBBits= (LPBYTE)pOldBits;
	::GlobalUnlock( hNewDib );
	::GlobalFree( hNewDib );
	::GlobalUnlock( hBufDib );
	::GlobalFree( hBufDib );
	
	return( TRUE );
}

BOOL CVideoPro::TempSobel(LPBYTE lpDIBBits, int lHeight, int lWidth,WINDOW w)
{
  // 模板高度
	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,0,0,0,-1,0,0,0,0};Rorbets算子
	  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+w.LeftX ) nX1 = nTempXc+w.LeftX;
	if( nY1 < nTempYc+w.BottomY ) nY1 = nTempYc+w.BottomY;
	if( nX2 < w.RightX - nTempW + nTempXc + 1) 
		nX2 = w.RightX- nTempW + nTempXc + 1;
	if( nY2 < w.TopY - nTempH + nTempYc + 1) 
		nY2 = w.TopY - nTempH + nTempYc + 1;
	TemplateOperation(lpDIBBits,aValue, fTempC, 
						 nTempW,  nTempH, nTempXc, nTempYc,
						  nX1,  nY1, 
						 nX2,  nY2,
						lHeight,lWidth );
	return TRUE;

}
//腐蚀运算
void CVideoPro::Erosion(LPBYTE lpDIBBits, int lHeight, int lWidth)
{
   //循环变量
	LONG i;
	LONG j;
	LONG m;
	LONG n;
	// 指向源图像的指针
	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);
	// 初始化新分配的内存,设定初始值为255
	lpDst = (LPBYTE)lpNewDIBBits;
	memset(lpDst, (BYTE)255, lLineBytes * lHeight);
	// 3×3的结构元素
	int T[9] = {0, 1, 0,
				1, 1, 1,
				0, 1, 0};
	// 使用水平方向的结构元素进行腐蚀
	for (i = 1; i < lHeight - 1; i++)
	{
		for (j = 3; j < lLineBytes - 3; j += 3)
		{
			// 由于使用3×3的结构元素,为防止越界,所以不处理最左、右、上、下四边的像素
			
			// 指向源图像倒数第j行,第i个象素的指针			
			lpSrc = (unsigned char *)(lpDIBBits + lLineBytes * i + j);

			// 指向目标图像倒数第j行,第i个象素的指针			
			lpDst = (unsigned char *)(lpNewDIBBits + lLineBytes * i + j);

			// 目标图像中的当前点先赋成bai色
			*lpDst = 255;
			*(lpDst + 1) = 255;
			*(lpDst + 2) = 255;
 
			// 如果源图像中3×3结构元素对应位置有白点	
			// 则将目标图像中的(0,0)点赋成hei色
			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 = 0;
						*(lpDst + 1) = 0;
						*(lpDst + 2) = 0;
						break;
					}
				}
			}				
		}
	}
	// 复制腐蚀后的图像
	memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight);
	// 释放内存
	LocalUnlock(hNewDIBBits);
	LocalFree(hNewDIBBits);
}
//膨胀Dilation
void CVideoPro::Dilation(LPBYTE lpDIBBits, int lHeight, int lWidth)
{
   //循环变量
	LONG i;
	LONG j;
	LONG m;
	LONG n;
	// 指向源图像的指针
	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);

	// 初始化新分配的内存,设定初始值为255
	lpDst = (LPBYTE)lpNewDIBBits;
	memset(lpDst, (BYTE)255, lLineBytes * lHeight);

	// 3×3的结构元素
	int T[9] = {0, 1, 0,
				1, 1, 1,
				0, 1, 0};

	// 使用水平方向的结构元素进行腐蚀
	for (i = 1; i < lHeight - 1; i++)
	{
		for (j = 3; j < lLineBytes - 3; j += 3)
		{
			// 由于使用3×3的结构元素,为防止越界,所以不处理最左、右、上、下四边的像素
			
			// 指向源图像倒数第j行,第i个象素的指针			
			lpSrc = (unsigned char *)(lpDIBBits + lLineBytes * i + j);

			// 指向目标图像倒数第j行,第i个象素的指针			

⌨️ 快捷键说明

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