k210 颜色追踪(寻找最大色块、stm32之间的串口通信、颜色预处理寻找色块函数)

K210云台追踪装置


1、摄像头配置

sensor.set_pixformat(sensor.RGB565)#设置为彩色
sensor.set_framesize(sensor.QVGA)#设置分辨率,即图像大小
sensor.skip_frames(time = 100)
#sensor.set_auto_gain(False)
#sensor.set_auto_whitebal(False)
sensor.set_vflip(True)#垂直方向翻转

进行图像的垂直方向翻转数据处理需求:在一些图像处理或者计算机视觉算法中,研究或者模型的训练可能需要统一图像的方向,以避免方向变化带来的影响。通过统一垂直方向的翻转,可以简化算法或模型的设计。


2、颜色预处理

  • 颜色预处理:

  • 颜色空间转换:通常将图像从RGB颜色空间转换为HSV(色相、饱和度、亮度)颜色空间。HSV颜色空间更适合进行颜色分析,因为它将颜色信息与亮度信息分开,使得颜色的描述更为直观和方便。
    颜色过滤:在HSV空间中,可以设定一个颜色的范围(如蓝色范围、红色范围等),通过设定上下限来选择所需颜色范围内的像素,从而过滤掉非目标颜色的像素。
    寻找最大色块:

在预处理过的图像中,可能会有多个符合颜色范围的区域(色块)。为了确定目标颜色的位置,可以使用以下技术:

  • 二值化:将符合颜色范围的像素转换为二值图像,即只有目标颜色的区域是白色(或者其他亮度值),其他区域是黑色。
  • 连通区域分析:找出二值图像中的连通区域(即连续的白色区域),计算每个区域的面积或像素数量。
  • 选择最大色块:通常选择面积最大的连通区域作为目标颜色的位置。这种做法可以有效排除噪声或其他不相关区域的干扰,确保追踪的准确性和稳定性。

2、1 寻找最大色块函数

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

这段代码是用来从一个包含多个色块(或者说连通区域)的列表 blobs 中找到面积(或像素数量)最大的色块,并返回该色块对象 max_blob。

  • max_size = 0:初始化一个变量 max_size,用来记录找到的最大色块的像素数量(或面积),初始值设为0。

  • max_blob = 0:初始化一个变量 max_blob,用来记录面积最大的色块对象,默认初始值为0。在实际使用中,可能会根据具体的数据结构或需求初始化为 None 或者其他适当的值。

  • for blob in blobs::遍历列表 blobs 中的每个色块对象 blob。

  • if blob.pixels() > max_size::检查当前遍历到的色块 blob 的像素数量(或面积)是否大于 max_size。

  • max_blob = blob 和 max_size = blob.pixels():如果当前 blob 的像素数量大于 max_size,则更新 max_blob 为当前的 blob 对象,并更新 max_size 为 blob 的像素数量。

最后,函数返回 max_blob,即面积最大的色块对象。

这段代码假设 blobs 是一个包含多个色块对象的列表,每个色块对象具有一个 pixels() 方法来获取其像素数量(或面积)。它通过遍历整个列表并比较每个色块的大小,来找到列表中面积最大的色块,并返回该色块对象。
过滤一些颜色小区域,可以在IDE右侧帧缓冲区框中选要识别的物体。框取红色物块后下面会显示其LAB的最大值和最小值,将thresholds列表修改即可
k210
~LAB色彩空间(LAB color space)是一种用于描述颜色的色彩模型。它不同于常见的RGB(红绿蓝)和CMYK(青、洋红、黄、黑)色彩空间,而是基于人眼的感知方式和颜色感知的模型。~
LAB色彩空间有三个通道:
L(亮度)通道:表示颜色的亮度或明暗程度。在L通道中,黑色是0,白色是100。

  • A通道:表示颜色从绿色到红色的范围。负值表示绿色,正值表示红色。B通道:表示颜色从蓝色到黄色的范围。负值表示蓝色,正值表示黄色
  • LAB色彩空间的一个显著特点是,它可以描述人眼视觉系统的亮度和颜色感知方式。因此,它在许多领域中被广泛用于颜色相关的应用,如图像处理、计算机视觉、印刷、摄影等。特别是在计算机视觉中,LAB色彩空间常用于颜色识别、颜色分割、颜色校正等任务,因为它可以有效地分离亮度信息和颜色信息,从而提供更加灵活和准确的颜色处理能力~

2、2 串口发送函数

from machine import UART
from fpioa_manager import fm # GPIO重定向函数
 
fm.register(18, fm.fpioa.UART1_TX, force=True)
uart_A = UART(UART.UART1,9600, 8, 0, 1, timeout=1000, read_buf_len=4096)
 
#串口打包发送函数
def sending_data(x,y):
    FH = bytearray([0x2C,0x12,x,y,0x5B])#拼字节
    uart_A.write(FH);
 
sending_data(cx,cy)#发送cx,cy变量

注册一个GPIO口配置为UART1的TX,波特率为9600,将要发送的数据打包为字符串的形式进行发送,数据包除要发送的变量外,还有帧头(0x2C、0x12)和帧尾(0x5B)


2、3 寻找色块函数

 img = sensor.snapshot()#拍摄一张照片,img为一个image对象,获取快照
    blobs=img.find_blobs([thresholds[0]], pixels_threshold=100, area_threshold=100, merge=True, margin=10)
    max_b=find_max(blobs)#寻找最大色块
    cx=0;cy=0;
#用for循环把所有的色块找一遍。
    if blobs:
 
       max_b = find_max(blobs)
       cx=max_b[5]
       cy=max_b[6]
       cw=max_b[2]
       ch=max_b[3]
       img.draw_rectangle(max_b.rect(),color=(0,0,0)) # rect
       img.draw_cross(max_b[5], max_b[6]) # cx, cy
  • img = sensor.snapshot(): 这行代码通过sensor对象获取当前图像的快照,并将其赋值给变量img,img是一个图像对象,可以进行后续处理。

  • blobs = img.find_blobs([thresholds[0]], pixels_threshold=100, area_threshold=100, merge=True, margin=10): 这行代码使用find_blobs方法在图像img中查找符合指定颜色阈值的色块。参数说明:

  • [thresholds[0]]: 是一个阈值列表,表示要查找的颜色阈值。thresholds[0]应该是预先定义的阈值。
    pixels_threshold=100: 指定了色块的像素阈值,即最小像素数,低于这个值的色块将被忽略。
    area_threshold=100: 指定了色块的面积阈值,即最小面积,小于这个值的色块也将被忽略。
    merge=True: 表示是否合并重叠的色块。
    margin=10: 表示在色块边界周围增加的边距。
    max_b = find_max(blobs): 这行代码调用find_max函数(假设已经定义,不在提供的代码中),并将blobs作为参数传递给它,返回找到的最大色块(或者是具有最大面积的色块)。

  • cx = max_b[5]: 将最大色块的中心点的 x 坐标存储在变量 cx 中。

  • cy = max_b[6]: 将最大色块的中心点的 y 坐标存储在变量 cy 中。

  • cw = max_b[2]: 将最大色块的宽度存储在变量 cw 中。

  • ch = max_b[3]: 将最大色块的高度存储在变量 ch 中。

  • img.draw_rectangle(max_b.rect(), color=(0, 0, 0)): 这行代码在图像 img 上绘制一个矩形,矩形的位置和大小由 max_b.rect() 提供,颜色为黑色 (0, 0, 0)。这个矩形通常用来标记识别出的色块区域。

  • img.draw_cross(max_b[5], max_b[6]): 这行代码在图像 img 上绘制一个交叉十字,位置由 max_b[5] 和 max_b[6] 给出,即最大色块的中心点坐标 (cx, cy)。这个交叉十字通常用来标记色块的中心位置。

2、4 stm32串口函数

2、4、1 初始化配置:

int Openmv_X; /*OPENMV X Öá·´À¡×ø±ê*/
int Openmv_Y; /*OPENMV X Öá·´À¡×ø±ê*/
        
                           
void Uart3_Init(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	
	USART_InitStructure.USART_BaudRate = 9600;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART3, &USART_InitStructure);
	
	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	USART_Cmd(USART3, ENABLE);
}
2、4、2 中断函数配置:
void USART3_IRQHandler(void)
{
    u8 com_data; // 定义接收到的数据变量
    u8 i;
    static u8 RxCounter1 = 0; // 接收计数器,用于记录接收到的字节数
    static u16 RxBuffer1[5] = {0}; // 接收缓冲区,存储接收到的数据
    static u8 RxState = 0;	// 接收状态机的状态变量

    if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  	// 检查是否接收数据寄存器非空中断已发生
    {
        flag = 1; // 设置一个标志位(假设flag是一个全局变量)
        USART_ClearITPendingBit(USART3, USART_IT_RXNE);  	// 清除中断挂起标志位
        com_data = USART_ReceiveData(USART3);		// 从USART3读取接收到的数据
        
        // 状态机处理接收到的数据
        if (RxState == 0 && com_data == 0x2C)  // 开始接收序列,期望接收0x2C
        {
            RxState = 1; // 进入状态1
            RxBuffer1[RxCounter1++] = com_data; // 将接收到的数据存入缓冲区
        }
        else if (RxState == 1 && com_data == 0x12)  // 在0x2C之后,期望接收0x12
        {
            RxState = 2; // 进入状态2
            RxBuffer1[RxCounter1++] = com_data; // 将接收到的数据存入缓冲区
        }
        else if (RxState == 2) // 接收数据状态
        {
            RxBuffer1[RxCounter1++] = com_data; // 将接收到的数据存入缓冲区

            // 检查终止条件(已接收5字节且最后一个字节是0x5B)
            if (RxCounter1 == 5 && com_data == 0x5B)
            {
                // 处理接收到的数据
                Openmv_X = RxBuffer1[RxCounter1 - 3]; // 假设第三个字节是Openmv_X
                Openmv_Y = RxBuffer1[RxCounter1 - 2]; // 假设第四个字节是Openmv_Y

                // 重置状态和缓冲区
                RxCounter1 = 0;
                RxState = 0;	
            }
            else if (RxCounter1 > 5) // 如果接收到超过5字节且没有终止条件
            {
                RxState = 0; // 重置状态
                RxCounter1 = 0; // 重置计数器
                for (i = 0; i < 5; i++)
                {
                    RxBuffer1[i] = 0x00; // 清空缓冲区
                }
            }
        }
        else // 无效状态,重置所有状态和缓冲区
        {
            RxState = 0; // 重置状态
            RxCounter1 = 0; // 重置计数器
            for (i = 0; i < 5; i++)
            {
                RxBuffer1[i] = 0x00; // 清空缓冲区
            }
        }
    }
}

相关推荐

  1. 力扣2379.得到k个黑最少涂次数

    2024-07-22 06:16:02       21 阅读
  2. 力扣-2379. 得到 K 个黑最少涂次数

    2024-07-22 06:16:02       26 阅读
  3. K210 UART串口通信介绍与 STM32通信

    2024-07-22 06:16:02       47 阅读
  4. D435+opencv识别

    2024-07-22 06:16:02       26 阅读
  5. 连通

    2024-07-22 06:16:02       26 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-22 06:16:02       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-22 06:16:02       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-22 06:16:02       45 阅读
  4. Python语言-面向对象

    2024-07-22 06:16:02       55 阅读

热门阅读

  1. 线段树分治+可撤销并查集 学习笔记

    2024-07-22 06:16:02       16 阅读
  2. 含有罗马字母的txt转换为csv文件读取-报错

    2024-07-22 06:16:02       12 阅读
  3. go标准库---net/http服务端

    2024-07-22 06:16:02       13 阅读
  4. python多进程库(multiprocessing)

    2024-07-22 06:16:02       17 阅读