23年电赛E题,k210智能识别与定位

#=============================================================
import sensor
import image
import lcd
import time
import machine
from machine import UART, Timer
from fpioa_manager import fm
import ustruct

import sensor, image, lcd, time
import KPU as kpu

import utime
from Maix import GPIO
from board import board_info

import math






# ************************* 一些变量的设定 *************************

min_blob_area = 1  # 最小色块面积阈值

x_offset = 0
y_offset = 0
position = "Center"  # 初始化 position

red_x = 160
red_y = 120

green_x = 160
green_y = 120

black_x = 160
black_y = 120

green_threshold =  (85, 97, -128, -22, 124, -128)  # 设定颜色色块参数
red_threshold = (75, 66, 10, 118, 89, -39)
red_threshold = (72, 100, -50, 127, -128, 127)
black_threshold = (39, 1, -128, 127, -41, 57)


#labels = ['1', '2', '3', '4', '5', '6', '7', '8']
labels = ['0', '1']
color_R = (255, 0, 0)
color_G = (0, 255, 0)
color_B = (0, 0, 255)
color_BLACK = (0,0,0)
color_WHITE = (255,255,255)
# ************************* 摄像头画面的初始化 *************************
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
# 如果对输入的镜头有格式要求
img_width = 240
img_height = 240
sensor_window = (img_width,img_height)
sensor_hmirror = False
sensor_vflip = True
sensor.set_windowing(sensor_window)
sensor.set_hmirror(sensor_hmirror)
sensor.set_vflip(sensor_vflip)
sensor.run(1)
#sensor.skip_frames()   #跳过一些图片让摄像头稳定


# ************************* lcd画面的初始化 *************************
lcd.init(type=1)  #type=1正常,type=2反色
#lcd.init(freq = 1500000)
lcd.rotation(0)   #旋转方向  0-0°  1-90°  2-180° 3-270°

#lcd.display(img)  # 显示图像   #在后续完成了位置的标注后,再进行显示

#img.draw_string(50, 50, "img") #在图片上写字
#lcd.draw_string(0, 0, "lcd")   #在lcd上写字 #最好在图片上写字,因为这种翻转是有用的

# ************************* 串口的初始化设置 *************************
fm.register(24, fm.fpioa.UART1_TX, force=True)
fm.register(25, fm.fpioa.UART1_RX, force=True)
uart_A = UART(UART.UART1, 9600, 8, 0, 0, timeout=1000, read_buf_len=4096)
uart_A.write(b'ready\r\n')


# ************************* 定时器的中断 *************************
def send_data(timer):
    data = "none\r\n".encode()
    uart_A.write(data)
'''
    if classID != -1:
        abs_x_offset_str = str(abs(x_offset))
        data = labels[classID].encode() + ":".encode() + position.encode() + abs_x_offset_str.encode() + "\r\n".encode()
    else:
        data = "none\r\n".encode()
'''
tim = Timer(Timer.TIMER0, Timer.CHANNEL0, mode=Timer.MODE_PERIODIC, period=500, unit=Timer.UNIT_MS, callback=send_data)

# ************************ 循迹黑色的线 **************************
def track_task():
    red_roi_size = 30  # 十字架的尺寸,根据需要调整
    # 计算子区域的左上角和右下角坐标
    roi_left = max(red_x - red_roi_size, 0)  # 左上角x坐标,不能小于0
    roi_top = max(red_y - red_roi_size, 0)   # 左上角y坐标,不能小于0
    roi_right = min(red_x + red_roi_size, img_width)    # 右下角x坐标,不能大于图像宽度
    roi_bottom = min(red_y + red_roi_size, img_height)  # 右下角y坐标,不能大于图像高度
    #print("left:",roi_left," top:",roi_top," right:",roi_right," bottom:",roi_bottom)
    # 处理边界情况,确保子区域不超出图像范围
    red_roi_region = img.copy(roi=(roi_left, roi_top, roi_right, roi_bottom))

    blobs = red_roi_region.find_blobs([black_threshold])  # 在img中找色块
    #blobs = img.find_blobs([black_threshold])  # 在img中找色块
    if blobs:
        # 对色块按面积进行排序,从大到小
        blobs = sorted(blobs, key=lambda b: b.area(), reverse=True)

        #for b in blobs:
        for i, b in enumerate(blobs):
            if i > 0:  # 只处理前三个最大的目标
                break


            if b.area() > min_blob_area:  # 判断色块面积是否大于阈值
                # 进行框图表示
                itemROL = b.rect()
                x, y, w, h = itemROL
                print("x:",x," y:",y," w=",w," h=",h)
                abs_x = x+roi_left
                abs_y = y+roi_top
                itemROL = (abs_x, abs_y, w, h)
                #print("x:",abs_x," y:",abs_y," w=",w," h=",h)
                img.draw_rectangle(itemROL,scale=2, color=color_WHITE)     # 画一个矩形框出目标
                img.draw_cross(roi_left+b.cx(), roi_top+b.cy(), color=color_WHITE)  # 在图像中心画十字叉
                img.draw_string(abs_x, abs_y-20,"B", scale=2, color=color_WHITE)

                global black_x
                global black_y
                black_x = abs_x
                black_y = abs_y







# ************************* 寻找色块 *************************

while True:
    img = sensor.snapshot()

    # ----------------------- 黑色方块 ------------------------

    #img = img.to_grayscale(copy=False)
    # 将图像转换为灰度图像
    '''
    img_gray = img.to_grayscale(copy=True)

    # 找到边缘中的直线段
    lines = img_gray.find_lines()
    '''

    lines = img.find_lines()
    # 在图像上绘制直线
    i=0
    for i,l in lines:
        # 只处理较长的直线段
        if l.length() > 100:
            # 获取直线段的两个端点坐标
            x1, y1, x2, y2 = l.line()

            # 在图像上画线
            img.draw_line((x1, y1, x2, y2), color=color_B, thickness=5)
            print("i="i,"  x1=",x1," y1=",y1,"   x2=",x2," y2=",y2)

    # 计算直线之间的交点
    i = 0
    for i in range(len(lines)):
        for j in range(i + 1, len(lines)):
            line1 = lines[i]
            line2 = lines[j]

            # 获取直线参数
            theta1 = line1.theta()  # 直线1的角度
            rho1 = line1.rho()      # 直线1的p值

            theta2 = line2.theta()  # 直线2的角度
            rho2 = line2.rho()      # 直线2的p值

            # 判断两条直线是否平行
            if abs(theta1 - theta2) < 1e-2:
                continue

            # 计算交点坐标
            x = (rho2 * math.sin(math.radians(theta1)) - rho1 * math.sin(math.radians(theta2))) / (math.cos(math.radians(theta1 - theta2))+0.1)
            y = (rho1 - x * math.cos(math.radians(theta1))) / (math.sin(math.radians(theta1))+0.1)

            # 在图像上画交点
            img.draw_circle(int(x), int(y), 5, color=(0, 0, 255), fill=True)

    # ----------------------- 红色色块 ------------------------
    blobs = img.find_blobs([red_threshold])  # 在img中找色块
    if blobs:
        # 对色块按面积进行排序,从大到小
        blobs = sorted(blobs, key=lambda b: b.area(), reverse=True)

        #for b in blobs:
        for i, b in enumerate(blobs):
            if i > 0:  # 只处理前三个最大的目标
                break


            if b.area() > min_blob_area:  # 判断色块面积是否大于阈值
                # 进行框图表示
                itemROL = b.rect()
                x, y, w, h = itemROL
                img.draw_rectangle(itemROL,scale=2, color=color_R)     # 画一个矩形框出目标
                img.draw_cross(b.cx(), b.cy(),color=color_R)  # 在图像中心画十字叉
                img.draw_string(x, y-20,"R", scale=2, color=color_R)

                red_x = b.cx()
                red_y = b.cy()

                #识别红点周围的黑色线
                #track_task()



    # ----------------------- 绿色色块 ------------------------
    blobs = img.find_blobs([green_threshold])  # 在img中找色块
    if blobs:
        # 对色块按面积进行排序,从大到小
        blobs = sorted(blobs, key=lambda b: b.area(), reverse=True)

        #for b in blobs:
        i = 0
        for i, b in enumerate(blobs):
            if i > 0:  # 只处理前三个最大的目标
                break


            if b.area() > min_blob_area:  # 判断色块面积是否大于阈值
                # 进行框图表示
                itemROL = b.rect()
                x, y, w, h = itemROL
                img.draw_rectangle(itemROL,scale=2, color=color_G)     # 画一个矩形框出目标
                img.draw_cross(b.cx(), b.cy(),color=color_G)  # 在图像中心画十字叉
                img.draw_string(x, y-20,"G", scale=2, color=color_G)

                green_x = b.cx()
                green_y = b.cy()


    lcd.display(img)  # 先显示图像

    lcd.draw_string(10, 10, " RED :" + str(red_x) +','+ str(red_y), lcd.RED, lcd.BLACK)  # 再显示文字
    lcd.draw_string(10, 30, "BLACK:" + str(black_x) +','+ str(black_y), lcd.WHITE, lcd.BLACK)  # 再显示文字
    lcd.draw_string(10, 50, "GREEN:" + str(green_x) +','+ str(green_y), lcd.GREEN, lcd.BLACK)  # 再显示文字


# ************************* yolo v2 *************************
'''
my_model = kpu.load(0x300000)
#anchors = [0.84, 1.22, 1.66, 2.34, 1.31, 1.75, 1.88, 2.59, 1.47, 2.09]
anchors = [3.8125, 3.8125, 5.375, 5.375, 7.1875, 7.1875, 11.25, 11.3125, 9.125, 9.125]
_ = kpu.init_yolo2(my_model, 0.5, 0.3, 5, anchors)
while True:
    img = sensor.snapshot()
    objects = kpu.run_yolo2(my_model,img)
    if objects:
        for obj in objects:
            confidence = obj.value()
            itemROL = obj.rect()
            classID = int(obj.classid())
            x, y, w, h = itemROL

            # 在相应位置,标注
            img.draw_rectangle(itemROL)     # 画一个矩形框出目标
            img.draw_cross(x+w//2, y+h//2)  # 在图像中心画十字叉
            img.draw_string(x, y-20,"%s : %.2f" %(labels[classID], confidence), scale=2, color=color_R)

            # 标注出位置
            x_offset = x+w//2 - img.width()//2  # X轴偏移量
            y_offset = y+h//2 - img.height()//2  # Y轴偏移量
            if x_offset > 50:
                position = "right"
            elif x_offset < -50:
                position = "left"
            else:
                position = "Center"

            img.draw_string(x, y+10, "%s : %d"%(position,x_offset))
    else:
        classID = -1

    lcd.display(img)  # 先显示图像
    #lcd.draw_string(10, 10, "Position: " + position, lcd.WHITE, lcd.BLACK)  # 再显示文字
    #lcd.draw_string(10, 30, "X Offset: " + str(x_offset), lcd.WHITE, lcd.BLACK)  # 显示X轴偏移
    #lcd.draw_string(10, 50, "Y Offset: " + str(y_offset), lcd.WHITE, lcd.BLACK)  # 显示Y轴偏移
'''


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值