基于野火3.2寸LCD代码进行颜色识别与追踪(stm32f103zet6)

RGB转化为HSV

首先将rgb转化为hsv,代码如下图所示

			READ_FIFO_PIXEL(Camera_Data);		/* 从FIFO读出一个rgb565像素到Camera_Data变量 */
			
			R = Camera_Data & 0xF800;
	    G = Camera_Data & 0x07E0;
	    B = Camera_Data & 0x001F;

			if (j%10==0 && i%10==0)		//rgb转换为hsv
			{
			float rr,gg,bb;
			R=R>>11;
			G=G>>5;				
			rr=R/(float)32;
			gg=G/(float)64;
			bb=B/(float)32;
			float h,s,v;
			float max=0;
			float min=0;
			max = rr;
      if(max<gg)
      max = gg;
      if(max<bb)
      max = bb;
			min = rr;
      if(min>gg)
        min = gg;
			if(min>bb)
					min = bb;
			v = max;
			if(max == 0)
					s = 0;
			else
					s = 1 - (min/max);
 
    if(max == min)
        h = 0;
    else if(max == rr && gg>=bb)
        h = 60*((gg-bb)/(max-min));
    else if(max == rr && gg<bb)
        h = 60*((gg-bb)/(max-min)) + 360;
    else if(max == gg)
        h = 60*((bb-rr)/(max-min)) + 120;
    else if(max == bb)
        h = 60*((rr-gg)/(max-min)) + 240;
    v = v * 100;
		s = s * 100;

这里每一个循环里面需要开一个窗口然后在之后需要对每一个窗口进行赋值,按道理可以在循环外面开一个240*320的窗口,但是尝试之后效果与预期不同。

计算HSV阈值

在转化为hsv之后就可以计算出中间区域的hsv值,方便后期设置物体hsv的阈值,计算代码如图

循环之内的函数

				if (j>160-14&j<160+14&i>120-14&i<120+14)		//计算中心处hsv的值
				{
				sum_h=sum_h+h;
				sum_s=sum_s+s;
				sum_v=sum_v+v;
				size_hsv++;
					}			

循环外的函数(这里是打印出来,可以用自己输出函数)

				sprintf(hchar,"h=%.5f",sum_h/size_hsv);
				sprintf(schar,"s=%.5f",sum_s/size_hsv);
				sprintf(vchar,"v=%.5f",sum_v/size_hsv); 
				ILI9341_DispString_EN (0,0, &hchar[0] );
				ILI9341_DispString_EN (0,30, &schar[0] );
				ILI9341_DispString_EN (0,60, &vchar[0] );

由于平均值是在循环结束之后计算得出,所以需要在循环结束之后打印出来。

实验效果如图:

判断HSV阈值

通过hsv的值计算出图像的上下hsv的阈值,在函数里面添加一个判断条件,只有在hsv阈值内的才显示白色的点,为了加快计算速度,函数中选择每十个点计算一次。

函数如图所示:定义阈值变量

	uint16_t R, G, B, H_hi = 70, H_lo = 20, S_hi = 70, S_lo = 20, V_hi = 100, V_lo = 60;
			if( (h>H_lo && h<H_hi) && (s>S_lo && s<S_hi)  && (v>V_lo && v<V_hi)) //根据阈值判断目标物体,并取中心点的
			{

				sum_x=sum_x+j;
				sum_y=sum_y+i;
				size_points++;
				Camera_Data = 0xffff;
				
			}
			else	Camera_Data = 0x0000;

实验效果如图:

 

色块中心坐标提取:

循环内:

			if( (h>H_lo && h<H_hi) && (s>S_lo && s<S_hi)  && (v>V_lo && v<V_hi)) //根据阈值判断目标物体,并取中心点的
			{

				sum_x=sum_x+j;
				sum_y=sum_y+i;
				size_points++;
				Camera_Data = 0xffff;
				
			}
			else	Camera_Data = 0x0000;

循环外:

			center_objx=sum_x/size_points;
			center_objy=sum_y/size_points;

轨迹描画

代码如图:

			if (num_cal < 5)
				{
					centerx[num_cal]=center_objx;
					centery[num_cal]=center_objy;
				}
			else
				{
					centerx[0]=centerx[1];
					centerx[1]=centerx[2];
					centerx[2]=centerx[3];
					centerx[3]=centerx[4];
					centerx[4]=center_objx;
					centery[0]=centery[1];
					centery[1]=centery[2];
					centery[2]=centery[3];
					centery[3]=centery[4];
					centery[4]=center_objy;
				}
			num_cal++;
				if(num_cal > 5)
				{
					for (int i=0;i<4;i++)
					{
						ILI9341_DrawLine(centerx[i], centery[i], centerx[i+1], centery[i+1]);
					}
				}

解释:首先先记录前五个中心点位置的值,然后第六个值覆盖第五个值,第四个值覆盖第三个值,以此类推,最后将这五个值连线出来即可,这里需要注意,由于每一帧图片都要记录出目标的中心坐标,也需要记录之前帧图像的目标的中心坐标,所以这里的变量都需要设置为static,使得跳出函数时临时变量不清空。

效果如图:

总体代码如下

void ImagDisp(uint16_t sx,uint16_t sy,uint16_t width,uint16_t height)
{
	uint16_t i, j; 
	uint16_t Camera_Data;
	uint16_t R, G, B, H_hi = 70, H_lo = 20, S_hi = 70, S_lo = 20, V_hi = 100, V_lo = 60;
	double sum_h=0,sum_s=0,sum_v=0,size_hsv=0;
	char hchar[20],schar[20],vchar[20];
	uint16_t sum_x=0,sum_y=0,size_points=0;		
static uint8_t num_cal;
static float centerx[5],centery[5];
	float center_objx,center_objy;
	
//	ILI9341_OpenWindow(sx,sy,width,height);
//	ILI9341_Write_Cmd ( CMD_SetPixel );	

	for(i = 0; i < 240; i++)
	{
		for(j = 0; j < 320; j++)
		{
			ILI9341_OpenWindow ( j, i, 1, 1 );
			ILI9341_Write_Cmd ( CMD_SetPixel );	
			
			READ_FIFO_PIXEL(Camera_Data);		/* 从FIFO读出一个rgb565像素到Camera_Data变量 */
			
			R = Camera_Data & 0xF800;
	    G = Camera_Data & 0x07E0;
	    B = Camera_Data & 0x001F;

			if (j%10==0 && i%10==0)		//rgb转换为hsv
			{
			float rr,gg,bb;
			R=R>>11;
			G=G>>5;				
			rr=R/(float)32;
			gg=G/(float)64;
			bb=B/(float)32;
			float h,s,v;
			float max=0;
			float min=0;
			max = rr;
      if(max<gg)
      max = gg;
      if(max<bb)
      max = bb;
			min = rr;
      if(min>gg)
        min = gg;
			if(min>bb)
					min = bb;
			v = max;
			if(max == 0)
					s = 0;
			else
					s = 1 - (min/max);
 
    if(max == min)
        h = 0;
    else if(max == rr && gg>=bb)
        h = 60*((gg-bb)/(max-min));
    else if(max == rr && gg<bb)
        h = 60*((gg-bb)/(max-min)) + 360;
    else if(max == gg)
        h = 60*((bb-rr)/(max-min)) + 120;
    else if(max == bb)
        h = 60*((rr-gg)/(max-min)) + 240;
    v = v * 100;
		s = s * 100;
		
		

			if( (h>H_lo && h<H_hi) && (s>S_lo && s<S_hi)  && (v>V_lo && v<V_hi)) //根据阈值判断目标物体,并取中心点的
			{

				sum_x=sum_x+j;
				sum_y=sum_y+i;
				size_points++;
				Camera_Data = 0xffff;
				
			}
			else	Camera_Data = 0x0000;
			
			ILI9341_Write_Data(Camera_Data);
			
			
//				if (j>160-14&j<160+14&i>120-14&i<120+14)		//计算中心处hsv的值
//				{
//				sum_h=sum_h+h;
//				sum_s=sum_s+s;
//				sum_v=sum_v+v;
//				size_hsv++;
//					}			
			}
	}
 }
			center_objx=sum_x/size_points;
			center_objy=sum_y/size_points;
 
			if (num_cal < 5)
				{
					centerx[num_cal]=center_objx;
					centery[num_cal]=center_objy;
				}
			else
				{
					centerx[0]=centerx[1];
					centerx[1]=centerx[2];
					centerx[2]=centerx[3];
					centerx[3]=centerx[4];
					centerx[4]=center_objx;
					centery[0]=centery[1];
					centery[1]=centery[2];
					centery[2]=centery[3];
					centery[3]=centery[4];
					centery[4]=center_objy;
				}
			num_cal++;
				if(num_cal > 5)
				{
					for (int i=0;i<4;i++)
					{
						ILI9341_DrawLine(centerx[i], centery[i], centerx[i+1], centery[i+1]);
					}
				}
 
 
//				sprintf(hchar,"h=%.5f",sum_h/size_hsv);
//				sprintf(schar,"s=%.5f",sum_s/size_hsv);
//				sprintf(vchar,"v=%.5f",sum_v/size_hsv); 
//				ILI9341_DispString_EN (0,0, &hchar[0] );
//				ILI9341_DispString_EN (0,30, &schar[0] );
//				ILI9341_DispString_EN (0,60, &vchar[0] );
}

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32颜色识别追踪算法腐蚀算法,是一种图像处理算法,用于改善颜色识别追踪的准确性和鲁棒性。 腐蚀算法是一种形态学运算,可以通过与图像中的像素进行比较,来改变像素的值和结构。在颜色识别追踪中,腐蚀算法可以用于去除图像中的噪点和细小的不规则形状,从而提高对目标颜色识别能力。 具体来说,腐蚀算法可以通过以下步骤实现: 1. 选择合适的结构元素。结构元素是一个小的模板,通常用于定义腐蚀过程中要考虑的像素的邻域。 2. 将结构元素与原始图像进行卷积。卷积过程中,将结构元素的中心与原始图像的每一个像素进行比较,并根据预定义的条件(如像素值的大小、相等性等),来确定输出图像中的像素。 3. 根据卷积结果,生成腐蚀后的图像。腐蚀操作通常会将图像中边缘的像素值设置为0,从而实现去除噪点和收缩图像边缘的效果。 在STM32颜色识别追踪算法中,腐蚀算法可以用于去除图像中的不相关颜色,并将目标颜色的区域收缩为更准确的形状。这样,通过腐蚀算法处理后的图像,可以更容易地识别追踪目标颜色。 总之,STM32颜色识别追踪算法腐蚀算法是一种用于图像处理的方法,通过去除噪点和收缩图像边缘,提高目标颜色识别追踪的准确性和鲁棒性。它在各种应用场景中都具有广泛的应用前景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值