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

📄 global.cpp

📁 机器人视觉处理程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			{
				if(tempCntObstacle > theApp.nObstacleParm1 && bFoundObstacle == TRUE)
				{
					nCntObstacle += 1;           
					break;
				}
				bFoundObstacle = FALSE;
				tempCntObstacle = 0;
			}
				
		}
	}

	if(nCntObject >=theApp.nObjectParm2)    //modified 20->10
	{
		// 发现目标,得到位置参数,并返回TRUE
		theApp.xCoordinate /= nCntObject;
		theApp.yCoordinate /= nCntObject;				  
		theApp.bFlagObject=TRUE;
	}
	else							
		theApp.bFlagObject=FALSE; 
	
	if(nCntObstacle>=theApp.nObstacleParm2)	
		theApp.bFlagObstacle=TRUE;
	else
		theApp.bFlagObstacle=FALSE;		

}

/*================================================================================
*函数名:		BOOL SearchObjectSucess()
*函数参数:		无
*函数功能描述:  机器人找到目标物后处理函数
*返回值:	    void	
*==================================================================================*/
BOOL SearchObjectSucess()
{
		// 找到目标,停止运动					
		if(abs(theApp.xCoordinate - XROBOT) < 100 && abs(theApp.yCoordinate - YROBOT) < 200)
		{										//yCoordinate<YROBOT  ==1
			theApp.nMotiontype = STOP;			//先停止机器人
			Motion();
			::Sleep(100);                       //延时100ms
			theApp.nMotiontype = BEEP;			//再蜂鸣,表示找到目标物
			Motion();
			return  TRUE;
		}
		else
			return FALSE;		

}

/*================================================================================
*函数名:		BOOL SearchLine()
*函数参数:		无
*函数功能描述:	搜索图像以确定白线函数
*返回值:	    BOOL,TRUE-扫描到白线,FALSE-未扫描到白线	
*==================================================================================*/
//隔五行扫描,若每行白色象素点超过35,而且满足这样条件的行有16行,则认为由这些行围成的区域是白色区域
BOOL SearchLine()         
{
	int i, j, r, g, b;
	int tempCnt;
	int xTemp, yTemp;
	BOOL bFound = FALSE;
	theApp.nCntLinePts = 0;

	//处理图像白线
	for (i = 5; i < HEIGHT; i += 5)    //隔五行扫描
	{
		bFound = FALSE;
		tempCnt = 0;
		for (j = 0; j < WIDTH; ++j)
		{
			r=theApp.tempColor[(HEIGHT-i-1)*WIDTH*3+j*3+2];
			g=theApp.tempColor[(HEIGHT-i-1)*WIDTH*3+j*3+1];
			b=theApp.tempColor[(HEIGHT-i-1)*WIDTH*3+j*3+0];

			if(r == 255 && g == 255 && b == 255)
			{
				++tempCnt;
				if(bFound == FALSE)
				{
					bFound = TRUE;
					xTemp = j;
					yTemp = i;
				}
				if(tempCnt > theApp.nWhiteParm1 && bFound == TRUE && j > WIDTH - 6 && j < WIDTH - 2)     //? 至少减一  (j < WIDTH - 4)--> (j>WIDTH - 4) is  right  白色区域延伸至右边缘
				{
					theApp.linePoints[theApp.nCntLinePts][0] = (j + xTemp) / 2;
					theApp.linePoints[theApp.nCntLinePts][1] = (i + yTemp) / 2;
					++theApp.nCntLinePts;
					break;
				}
			}
			else
			{
				if(tempCnt > theApp.nWhiteParm1 && bFound == TRUE)                                      //??   白色区域在中间
				{
					theApp.linePoints[theApp.nCntLinePts][0] = (j + xTemp) / 2;
					theApp.linePoints[theApp.nCntLinePts][1] = (i + yTemp) / 2;
					++theApp.nCntLinePts;
					break;
				}
				bFound = FALSE;
				tempCnt = 0;
			}
		}
	}
		
	if(theApp.nCntLinePts >= theApp.nWhiteParm2/5)                         //每隔五行扫描
	{
		int centerX = 0,centerY = 0;
		int deltaX = 0;

		for(i = 0;i < theApp.nCntLinePts; ++i)
		{
			centerX += theApp.linePoints[i][0];
			centerY += theApp.linePoints[i][1];
		}
		centerX /= theApp.nCntLinePts;
		centerY /= theApp.nCntLinePts;

		// 归一化为相隔5行的横坐标差值,白线方向是\时,值为正,方向是/时,值为负
		for(i = 0;i < theApp.nCntLinePts - 1;++i)            //防止数组越界,theApp.linePoints[theApp.nCntLinePts][1]
			if(theApp.linePoints[i + 1][1] != theApp.linePoints[i][1])
				deltaX += (theApp.linePoints[i][0]          //deltaX--平均斜率 deltaX   =x/y  right
				- theApp.linePoints[i + 1][0]) / (theApp.linePoints[i + 1][1]  //*5-->删去
				- theApp.linePoints[i][1]);

		theApp.deltaAngle = deltaX / (theApp.nCntLinePts - 1);    //theApp.deltaAngle>0表明斜率为正,白线中线沿左下角到右上角的直线
																  //theApp.deltaAngle<0表明斜率为负,白线中线右下角左上角的直线

		// 公式:(centerX-X)/(YROBOT-centerY)=deltaAngle/5
		theApp.deltaLength = XROBOT - (centerX - (YROBOT - centerY) * theApp.deltaAngle ); //   /5-->删去
																	//theApp.deltaLength>0表明白线区域中心在机器人左边,否则在机器人右边
		return TRUE;
	}
	
	return FALSE;
}

/*================================================================================
*函数名:		void SobelEdgeDection()
*函数参数:		无
*函数功能描述:  sobel边缘检测算法,在形状识别中用到
				具体算法思想参见FAQ-->sobel边缘检测算法的思想是什么?				
*返回值:	    void	
*==================================================================================*/
void SobelEdgeDection()
{

	//边缘检测卷积核,对水平方向边缘响应最大
	int Gx[9];
	Gx[0]=-1;
	Gx[1]=0;
	Gx[2]=1;
	Gx[3]=-2;
	Gx[4]=0;
	Gx[5]=2;
	Gx[6]=-1;
	Gx[7]=0;
	Gx[8]=1;
	//边缘检测卷积核,对垂直方向边缘响应最大
	int Gy[9];
	Gy[0]=1;
	Gy[1]=2;
	Gy[2]=1;
	Gy[3]=0;
	Gy[4]=0;
	Gy[5]=0;
	Gy[6]=-1;
	Gy[7]=-2;
	Gy[8]=-1;
	

	int gradSum[WIDTH*HEIGHT]={0};
	int i,j;
	int Gradx,Grady;                       //注意类型转换
	for(i=1;i<HEIGHT-1;i++)
		for(j=1;j<WIDTH-1;j++)
		{
			Gradx=Gx[0]*theApp.tempColor[(i-1 ) * WIDTH * 3 + (j-1) * 3 + 0]
				+Gx[1]*theApp.tempColor[(i-1 ) * WIDTH * 3 + j * 3 + 0]
				+Gx[2]*theApp.tempColor[(i-1 ) * WIDTH * 3 + (j+1) * 3 + 0]
				+Gx[3]*theApp.tempColor[( i ) * WIDTH * 3 + (j-1) * 3 + 0]
				+Gx[4]*theApp.tempColor[( i ) * WIDTH * 3 + j * 3 + 0]
				+Gx[5]*theApp.tempColor[(i ) * WIDTH * 3 + (j+1) * 3 + 0]
				+Gx[6]*theApp.tempColor[(i+1 ) * WIDTH * 3 + (j-1) * 3 + 0]
				+Gx[7]*theApp.tempColor[(i+1) * WIDTH * 3 + j * 3 + 0]
				+Gx[8]*theApp.tempColor[(i+1 ) * WIDTH * 3 + (j+1) * 3 + 0];
			Grady=Gy[0]*theApp.tempColor[(i-1 ) * WIDTH * 3 + (j-1) * 3 + 0]
				+Gy[1]*theApp.tempColor[(i-1 ) * WIDTH * 3 + j * 3 + 0]
				+Gy[2]*theApp.tempColor[(i-1 ) * WIDTH * 3 + (j+1) * 3 + 0]
				+Gy[3]*theApp.tempColor[( i ) * WIDTH * 3 + (j-1) * 3 + 0]
				+Gy[4]*theApp.tempColor[( i ) * WIDTH * 3 + j * 3 + 0]
				+Gy[5]*theApp.tempColor[(i ) * WIDTH * 3 + (j+1) * 3 + 0]
				+Gy[6]*theApp.tempColor[(i+1 ) * WIDTH * 3 + (j-1) * 3 + 0]
				+Gy[7]*theApp.tempColor[(i+1) * WIDTH * 3 + j * 3 + 0]
				+Gy[8]*theApp.tempColor[(i+1 ) * WIDTH * 3 + (j+1) * 3 + 0];
			
			gradSum[( i ) * WIDTH  + j]=abs(Gradx)+abs(Grady);
				
		}
		for(i=1;i<HEIGHT-1;i++)
			for(j=1;j<WIDTH-1;j++)
			if(gradSum[( i ) * WIDTH  + j]>35)                 //35--边缘检测阈值,可根据需要改变
			{
				theApp.tempColor[( i ) * WIDTH * 3 + j * 3 + 0]=0;
				theApp.tempColor[( i ) * WIDTH * 3 + j * 3 + 1]=0;
				theApp.tempColor[( i ) * WIDTH * 3 + j * 3 + 2]=0;
			}
			else
			{
				theApp.tempColor[( i ) * WIDTH * 3 + j * 3 + 0]=255;
				theApp.tempColor[( i ) * WIDTH * 3 + j * 3 + 1]=255;
				theApp.tempColor[( i ) * WIDTH * 3 + j * 3 + 2]=255;
			}
	
}

/*================================================================================
*函数名:		void GrayScale()
*函数参数:		无
*函数功能描述:  彩色图像灰度化,在形状识别中用到
*返回值:	    void	
*==================================================================================*/
void GrayScale()
{
	BYTE r, g, b,gray;
	for(int i=0;i<HEIGHT;i++)
		for(int j=0;j<WIDTH;j++)
		{
			
			r=theApp.tempColor[(HEIGHT-i-1) * WIDTH * 3 + j * 3 + 2];
			g=theApp.tempColor[(HEIGHT-i-1) * WIDTH * 3 + j * 3 + 1];
			b=theApp.tempColor[(HEIGHT-i-1) * WIDTH * 3 + j * 3 + 0];

			gray = BYTE(0.299 * r + 0.587 * g + 0.114 * b);          //转化公式   

			theApp.tempColor[(HEIGHT-i-1) * WIDTH * 3 + j * 3 + 2]=gray;
			theApp.tempColor[(HEIGHT-i-1) * WIDTH * 3 + j * 3 + 1]=gray;
			theApp.tempColor[(HEIGHT-i-1) * WIDTH * 3 + j * 3 + 0]=gray;
		}
}
/*================================================================================
*函数名:		void FindOutObstacle()
*函数参数:		无
*函数功能描述:  发现障碍物后的处理函数
*返回值:	    void	
*==================================================================================*/
//处理策略是随机向左旋转90后前行或向右旋转90后前行
void FindOutObstacle()
{
	srand((unsigned)time(NULL));      
	int nRand=rand()%2;
	if(nRand == 1)
		theApp.nMotiontype = TURNLEFT90ANDRUN;     //向左旋转90后前行
	else
		theApp.nMotiontype = TURNRIGHT90ANDRUN;    //向右旋转90后前行

	Motion();
	return;

}

/*================================================================================
*函数名:		void FindOutCornerEdge()
*函数参数:		无
*函数功能描述:  发现拐角处边缘后的处理函数
*返回值:	    void	
*==================================================================================*/
void FindOutCornerEdge()
{
	if((theApp.bLeftEdge == TRUE) && (theApp.bRightEdge == TRUE))
		if(theApp.nLastMotiontype != STOP)						
			theApp.nMotiontype = STOP;
		else
			theApp.nMotiontype = ROTATION180ANDRUN;         
		
	Motion();
	return;

}
/*================================================================================
*函数名:		void FindOutEdge()
*函数参数:		无
*函数功能描述:  发现除拐角处边缘以外的边缘后处理函数
*返回值:	    void	
*==================================================================================*/
void FindOutEdge()
{
	if(((theApp.bTopEdge == TRUE) && (theApp.bLeftEdge == TRUE)) 
		|| ((theApp.bBottomEdge == TRUE) && (theApp.bLeftEdge == TRUE)))			//(左边缘和上边缘) 或 (左边缘和下行边缘) 同时在机器人视野
	{	
		if(theApp.nLastMotiontype != STOP)						
			theApp.nMotiontype = STOP;
		else
			theApp.nMotiontype = TURNRIGHT90ANDRUN;								//向右旋转	
	}
	else if(((theApp.bTopEdge == TRUE) && (theApp.bRightEdge == TRUE)) 
		|| ((theApp.bBottomEdge == TRUE) && (theApp.bRightEdge == TRUE))) 	//(右边缘和上边缘) 或 (右边缘和下行边缘)同时在机器人视野
	{	
		if(theApp.nLastMotiontype != STOP)
			theApp.nMotiontype = STOP;
		else
			theApp.nMotiontype = TURNLEFT90ANDRUN;								//向左旋转	
	}
	else if((theApp.bTopEdge == TRUE)									//机器若遇到了上行边缘或下行边缘
		|| (theApp.bBottomEdge == TRUE))
	{	
		if(( theApp.deltaxyEdgeLine >= XROBOT*2/30) && (theApp.deltaxyEdgeLine <= -XROBOT*2/30))					//行边缘近似是水平线
		{		         
			if(theApp.nLastMotiontype != STOP)
				theApp.nMotiontype = STOP;									//只是上边缘
			else
			{
				srand((unsigned)time(NULL));							
				int nRand=rand()%2;
				if(nRand==1)
					theApp.nMotiontype = TURNLEFT90ANDRUN;					//向左旋转90度
				else
					theApp.nMotiontype = TURNRIGHT90ANDRUN;					//向右旋转90度
			}				
    	
		}
		else if((theApp.deltaxyEdgeLine >- XROBOT*2/30)				
			&& (theApp.deltaxyEdgeLine <- (XROBOT*2)/(YROBOT/2)))
			{
			if(theApp.nLastMotiontype != STOP)
			theApp.nMotiontype = STOP;
			else
			theApp.nMotiontype = TURNLEFT;								//向左旋转
			}
	
		else if((theApp.deltaxyEdgeLine < XROBOT*2/30)			
			&& (theApp.deltaxyEdgeLine > (XROBOT*2)/(YROBOT/2)))
			{
			if(theApp.nLastMotiontype != STOP)
				theApp.nMotiontype = STOP;
			else
				theApp.nMotiontype = TURNRIGHT;							//向右旋转	
			}
			
	}
	else if(theApp.bLeftEdge == TRUE)
		{

		if(theApp.deltaxyEdgeColumn > XROBOT/YROBOT)                  
		{
				if( theApp.nLastMotiontype != STOP)
					theApp.nMotiontype = STOP;			
				else if(theApp.nLastMotiontype == STOP)				
					theApp.nMotiontype = TURNRIGHT;

		}
		else if((theApp.deltaxyEdgeColumn >= 30/YROBOT) 
				&& (theApp.deltaxyEdgeColumn <= XROBOT/YROBOT))			//左列边缘 /,斜率大于某个值
			{
				if( theApp.nLastMotiontype != STOP)
					theApp.nMotiontype = STOP;			
				else if(theApp.nLastMotiontype == STOP)				
					theApp.nMotiontype = TURNRIGHT;			
	

			}
			else if((theApp.deltaxyEdgeColumn <30 /YROBOT)
				&& (theApp.deltaxyEdgeColumn >= 0))
			{

				if(theApp.nLastMotiontype != STOP)
						theApp.nMotiontype = STOP;
				else														
					theApp.nMotiontype = FORWARD;				
			
			}
		}
	else if(theApp.bRightEdge == TRUE)
		{
			
		if(theApp.deltaxyEdgeColumn <- XROBOT/YROBOT)                
		{
				if( theApp.nLastMotiontype != STOP)
					theApp.nMotiontype = STOP;			
				else if(theApp.nLastMotiontype == STOP)					//这几行可能存在问题	
					theApp.nMotiontype = TURNLEFT;

		}
		else if((theApp.deltaxyEdgeColumn <= -30/YROBOT)
				&& (theApp.deltaxyEdgeColumn >=-XROBOT/YROBOT))  //左列边缘 /,斜率大于某个值
			{
				if(theApp.nLastMotiontype != STOP)			
					theApp.nMotiontype = STOP;				
				else if(theApp.nLastMotiontype == STOP)						//可能存在问题	
					theApp.nMotiontype = TURNLEFT;				

			}
			else if((theApp.deltaxyEdgeColumn >-30/YROBOT)
				&& (theApp.deltaxyEdgeColumn <=0))
			{
				if(theApp.nLastMotiontype != STOP)
					theApp.nMotiontype = STOP;	
				else 					
					theApp.nMotiontype = FORWARD;			
			                                      
			}
		}
		
		Motion();
		return;
}
/*================================================================================
*函数名:		void NotFindOutEdge()
*函数参数:		无
*函数功能描述:  未发现边缘处理函数
*返回值:	    void	
*==================================================================================*/
//处理策略是60%(3/5=0.6)的可能向前直走,20%(1/5=0.2)的可能向左转,20%(1/5=0.2)的可能向右转
void NotFindOutEdge()
{
	     
	    srand((unsigned)time(NULL));   
		int nRand = rand()%5;
		switch( nRand )
		{
		case 0:
		case 1:
		case 2:
			theApp.nMotiontype = FORWARD;   
			break;
		case 3:
			theApp.nMotiontype = TURNLEFT;   
			break;
		case 4:
			theApp.nMotiontype = TURNRIGHT; 
			break;
		}
		Motion();
		return;
}

/*================================================================================
*函数名:		void DecisionSearchObject()
*函数参数:		无
*函数功能描述:  寻找目标决策函数
*返回值:	    void	
*==================================================================================*/
void DecisionSearchObject()					//先后处理顺序
{

	SearchObjectAndObstacle();              //搜索目标和障碍物
	if(theApp.bFlagObject == TRUE)          //机器人视野范围内同时有障碍物和目标或边缘的处理原则
		return;								//只要发现目标物,则立即停止机器人.策略:发现目标物优先响应
			
		
	if(theApp.bFlagObstacle==TRUE)          //如果遇到障碍物则执行FindOutObstacle()
		FindOutObstacle();

//	SearchCornerEdge();
//		if((theApp.bLeftEdge == TRUE) && (theApp.bRightEdge == TRUE))
//		{
//		FindOutCornerEdge();
//		return;
//		}
	SearchEdge();							//搜索边缘
	if(theApp.bFlagEdge==TRUE)				//如果遇到边缘则执行FindOutEdge()
		FindOutEdge();
	else
		NotFindOutEdge();						//如果未遇到障碍物则执行NotFindEdge()
	
}

⌨️ 快捷键说明

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