【OpenMV学习笔记(一)】识别色块并与STM通信传输中心坐标

这篇具有很好参考价值的文章主要介绍了【OpenMV学习笔记(一)】识别色块并与STM通信传输中心坐标。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.前言

一直有想要写些东西的想法正好最近比较闲以及大创项目和电赛备赛需要用到OpenMV所以就记录一下学习过程。因为小白第一次写文章有什么错误希望大家包含在评论区指正。

2.硬件连接

2.1、Openmv端
openmv返回屏幕中心点坐标,笔记,OpenMV,学习,单片机,嵌入式硬件,视觉检测,stm32 这里OpenMV端仅作为数据的发送端,所以只需要共地,以及OpenMV的TX(P4)与开发板的RX端连接即可。
2.2、STM32端

openmv返回屏幕中心点坐标,笔记,OpenMV,学习,单片机,嵌入式硬件,视觉检测,stm32将开发板连接STM芯片RX端与转串口TX端的跳帽取下,再将OpenMV的TX端(P4)与STM的RX连接。如果使用USB转TTL则将TTL的RX端与STM的TX端连接,STM的RX端与OpenMV的TX端(P4)连接,然后共地,这样就可以在串口调试助手中查看数据的传输情况了。

3.代码

3.1、OpenMV端

# Blob Detection and uart transport
import sensor, image, time, math, pyb
from pyb import UART
import json
import ustruct
# For color tracking to work really well you should ideally be in a very, very,
# very, controlled enviroment where the lighting is constant...A
yellow_threshold   = (8, 22, -60, -3, 127, -128)
# You may need to tweak the above settings for tracking green things...
# Select an area in the Framebuffer to copy the color settings.


sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)       #设置图像大小QVGA大小为320*240,所以中心坐标应该是(160120)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False)             # must be turned off for color tracking
sensor.set_auto_whitebal(False)         # must be turned off for color tracking
red_threshold_01=(66, 31, -58, -24, 127, -128)
clock = time.clock()


uart = UART(3, 115200)
uart.init(115200, bits=8, parity=None, stop=1) # OpenMV端初始化与STM端配置一样即可。

#**************************传输数据的函数************************************
def sending_data(cx,cy):
    global uart;
    #frame=[0x2C,18,cx%0xff,int(cx/0xff),cy%0xff,int(cy/0xff),0x5B];
    #data = bytearray(frame)
    data = ustruct.pack("<bbhhb",               #格式为俩个字符俩个短整型(2字节)
                   0x2C,                        #帧头1
                   0x12,                        #帧头2
                   int(cx), # up sample by 4    #数据1
                   int(cy), # up sample by 4    #数据2
                   0x5B)
    uart.write(data);   #必须要传入一字节的数组,这个函数似乎不能发送单个字节,必须得一次发送多个字节
#**************************************************************************

#**************************找到最大的色块函数*******************************#
def find_max(blobs):
    max_size=0
    for blob in blobs:
        if blob.pixels() > max_size:
            max_blob=blob
            max_size = blob.pixels()
    return max_blob
#**************************************************************************#


while(True):
    img = sensor.snapshot() # Take a picture and return the image.

    blobs = img.find_blobs([yellow_threshold])
    if blobs:
        max_blob=find_max(blobs)
        #print('sum :', len(blobs))
        img.draw_rectangle(max_blob.rect())
        img.draw_cross(max_blob.cx(), max_blob.cy())
        output_str="[%d,%d]" % (max_blob.cx(),max_blob.cy())

        print('you send:',output_str)            #打印色块中心点坐标到串行终端便于数据核验
        sending_data(max_blob.cx(),max_blob.cy())#发送色块框的中心点坐标
        #FH = bytearray([0x2C,0x12,blobs[0].cx(),blobs[0].cy(),0x5B])

        #uart.write(FH)
    else:
        print('not found!')
        sending_data(567,789)#如果没有找到符合条件的色块,那么发送一个不可能出现的坐标
        #FH = bytearray([0x2C,0x12,0x77,0x55,0x5B])

        #uart.write(FH)

颜色识别:
这里只需要使用阈值编辑器,将想要识别的颜色调节到纯白色如下图所示,然后将下面的LAB阈值填入 red_threshold_01=() 即可。
openmv返回屏幕中心点坐标,笔记,OpenMV,学习,单片机,嵌入式硬件,视觉检测,stm32 获取中心坐标:
blob.rect() 返回这个色块的外框——矩形元组(x, y, w, h),可以直接在 image.draw_rectangle中使用。
blob.x() 返回色块的外框的x坐标(int),也可以通过blob[0]来获取。
blob.y() 返回色块的外框的y坐标(int),也可以通过blob[1]来获取。
blob.w() 返回色块的外框的宽度w(int),也可以通过blob[2]来获取。
blob.h() 返回色块的外框的高度h(int),也可以通过blob[3]来获取。
blob.pixels() 返回色块的像素数量(int),也可以通过blob[4]来获取。
blob.cx() 返回色块的外框的中心x坐标(int),也可以通过blob[5]来获取。
blob.cy() 返回色块的外框的中心y坐标(int),也可以通过blob[6]来获取。

3.2、STM32端

void DEBUG_USART_IRQHandler(void)                                
{
    uint8_t com_data; 
		uint8_t i;
		static uint8_t   RxCounter1=0;
		static uint16_t  RxBuffer1[7]={0};
		static uint8_t   RxState = 0;	
//		static uint8_t   RxFlag1 = 0;

		if( USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)  	   //接收中断  
		{ 
				USART_ClearITPendingBit(USART1,USART_IT_RXNE);       //清除中断标志
				com_data = USART_ReceiveData(DEBUG_USARTx );
			
				if(RxState==0&&com_data==0x2C)          //0x2c帧头
				{
					RxState=1;
					RxBuffer1[RxCounter1++]=com_data;     //RxBuffer1[0]==0x2c RxCounter1==1
				}
		
				else if(RxState==1&&com_data==0x12)     //0x12帧头
				{
					RxState=2;
					RxBuffer1[RxCounter1++]=com_data;     //RxBuffer1[0]==0x12 RxCounter1==2
				}
		
				else if(RxState==2)                     //开始接收有效数据
				{
					RxBuffer1[RxCounter1++]=com_data;     //全部接收完,RxCounter1==7

					if(RxCounter1>=7||com_data == 0x5B)  //RxBuffer1接受满了,接收数据结束
					{
					  RxState=3;
//						RxFlag1=1;
						Cx=(RxBuffer1[RxCounter1-4]<<8)+(RxBuffer1[RxCounter1-5]);    //RxBuffer1[2]是openmv发送的第一个数据的低八位,RxBuffer1[3]是openmv发送的第一个数据的高八位
						Cy=(RxBuffer1[RxCounter1-2]<<8)+(RxBuffer1[RxCounter1-3]);    //RxBuffer1[4]是openmv发送的第二个数据的低八位,RxBuffer1[5]是openmv发送的第二个数据的高八位
			    	printf("X=%d,Y=%d\n",Cx,Cy);
		            delay_ms(300);       //延时防止大量数据造成上位机卡顿
					}
				}
		
				else if(RxState==3)		//检测是否接受到结束标志
				{
						if(RxBuffer1[RxCounter1-1] == 0x5B)
						{
									USART_ITConfig(DEBUG_USARTx,USART_IT_RXNE,DISABLE);//关闭DTSABLE中断
//									if(RxFlag1)
//									{
//									
//									OLED_ShowNum(0,0,Cx,3,1,2);
//									OLED_ShowNum(0,2,Cy,3,1,2);
//									
//									}
//									RxFlag1 = 0;
									RxCounter1 = 0;
									RxState = 0;
									USART_ITConfig(DEBUG_USARTx,USART_IT_RXNE,ENABLE);
						}
						else   //接收错误
						{
									RxState = 0;
									RxCounter1=0;
									for(i=0;i<7;i++)
									{
											RxBuffer1[i]=0xff;      //将存放数据数组清零
									}
						}
				} 
	
				else   //接收异常
				{
						RxState = 0;
						RxCounter1=0;
						for(i=0;i<7;i++)
						{
								RxBuffer1[i]=0xff;      //将存放数据数组清零
						}
				}

		}

} 
			

看到这里或许会存在疑问,为什么我们发送五个数据却要定义一个七位的数据的接收数组呢?在OpenMV端的发送函数里面有一个"<bbhhb"的数据声明,其中b表示C语言的signed char类型占一个字节八位二进制数,h表示C语言的short类型占两个字节十六位二进制数。而我们的OpenMV一次只能发送一个字节八位二进制数,因此实际传输的数据为:数据帧1->数据帧2->数据1的低八位->数据1的高八位->数据2的低八位->数据2的高八位->数据帧3。至于为什么数据要使用两个字节,那是因为我们选择的是QVGA即320*240大小的图像,因此数据将会超过255即一个字节八位二进制数。

4.查看结果

openmv返回屏幕中心点坐标,笔记,OpenMV,学习,单片机,嵌入式硬件,视觉检测,stm32左边是OpenMV IDE串行终端的数据,右边是调试助手中的数据。可以发现虽然延时导致部分数据没有被打印出来但是调试助手中的数据全部来自串行终端,所以代码正确。

5.总结

代码部分参考了这篇文章写的很好很详细。完整的工程代码可以去Gitee下载。文章来源地址https://www.toymoban.com/news/detail-634314.html

到了这里,关于【OpenMV学习笔记(一)】识别色块并与STM通信传输中心坐标的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • openmv与stm32串口通信数据传输

    在openmv与stm32数据传输过程中遇到了奇怪的问题。 先说明我遇到的问题,后面又源码。 若发现问题-------或者有什么想法-------还望指教!!! 我的目的: openmv矩形识别,获取中心点坐标,通过串口发给stm32接受数据 我在main函数中,将存放的数据打印出来,然而并没有。如图

    2024年02月15日
    浏览(41)
  • 关于openmv与stm32通信数据传输遇到的问题

      遇到smt32与openmv无法通信,或者数据对不上。 上面的是openmv端发给stm32端的数据 %c4 b‘  ’:是stm32打印接收到的数据  逐个排查: openmv与pc端串口助手正常发收。stm32与pc端也可以正常发,但是接收数据的时候不能正常接收。 利用LED灯debug。   确定问题出在stm32端的中断服

    2024年02月15日
    浏览(30)
  • OpenMV4 基于色块识别的图形+颜色+坐标识别代码(micropython)

    Hello大家好,最近竞赛需要开始研究OpenMV4,今天和大家分享一段基于 色块识别的图形+颜色+坐标识别代码 ,实测准确率高于90%哦,当然,需要在光线和距离都合适的情况下使用(假如你的识别结果不尽如人意,可以自行调节颜色阈值和目标与摄像头的距离),下面,话不多说

    2024年02月15日
    浏览(39)
  • 【OpenMV+STM32】PID控制二维自由舵机色块追踪

    1、芯片:STM32F407ZGT6 2、CubeMX 3、KEIL5 4、OpenMV  5、舵机         利用由两个自由舵机组装而成的二维云台来控制OpenMV的位置,以实现追踪指定阈值色块的效果。 3.1 初始化配置 3.2 定时器配置(PWM波输出)         这里我使用TIM3的通道1和TIM4的通道1分别实现对两个舵机

    2024年03月19日
    浏览(50)
  • openmv和STM32串口通信识别条形码、二维码(HAL库)

    因为自己的毕设用到了条形码识别,所以在这里写一篇关于使用openmv识别条形码和二维码并且与STM32实现串口通讯,希望能帮到以后用到这一模块的同学,STM32方面我使用的是STM32F103RCT6,并且使用HAL进行编写代码。 OpenMV端:由图知UART_RX—P5 ------ UART_TX—P4 2.STM32端:这里我使用

    2023年04月13日
    浏览(47)
  • 学习记录之openmv和STM32F103的通信

    分上下位机,下位机向上位机发送数据。(上位机控制,下位机收集数据) 可能用到的函数: UART :通用异步 收/发器 USART :通用同步/异步 收/发器 USART_ init() 串口初始化:波特率、数据字长,奇偶校验,硬件流控及收发使能 USART_ Cmd 使能串口                             

    2024年02月14日
    浏览(40)
  • Mediapipe手势识别,并与unity通信

    Mediapipe是goole的一个开源项目,支持跨平台的常用ML方案,详情请戳下面链接 MediaPipe Mediapipe底层封装了手势识别的具体实现内容,而在Python中搭建完环境后经过很简单的调用就能够实现手势识别 环境如下: pip install mediapipe pip install opencv-python 简单的实现,代码很少,代码如

    2024年02月11日
    浏览(40)
  • openmv传承(二):色块检测

    这个色块检测真的没什么可以说的,非常简单烧一下例程,改一下阈值就可以使用 获取所需要修改的阈值  四、主要函数讲解 通过find_blobs函数可以找到色块。 thresholds是颜色的阈值,注意:这个参数是一个列表,可以包含多个颜色。如果你只需要一个颜色,那么在这个列表

    2024年02月13日
    浏览(54)
  • K210识别数字(0~9)并与单片机通信通过数字来控制小车移动

    前一段时间学习了K210的模型训练,又学会了K210的串口通信,于是冒出一个新奇的想法,用手势控制小车,手势识别可能比较难,于是想着先用数字控制小车。(懂得都懂)我相信有很多人再找这篇博客,希望大家可以看到这篇博客并帮助到你们。 方法也很简单,相信你看了

    2023年04月16日
    浏览(47)
  • 【STM32+OPENMV】矩形识别

    有关OPENMV最大色块追踪及与STM32通信内容,详情见【STM32+HAL】与OpenMV通信 1、芯片:STM32F103C8T6 2、CUBEMX配置软件 3、KEIL5 4、OPENMV 寻找黑色矩形,并将最大矩形的四个边缘坐标发送给STM32 1、寻找最大的矩形,并沿矩形边框绘制线条 2、完整通信+识别代码 【STM32+OPENMV】矩形识别资

    2024年03月15日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包