电赛滚球控制系统树莓派代码

电赛滚球控制系统树莓派代码

基础加发挥部分
图像二值化后,提取最大色块获得坐标即为小球坐标
只提取图像中间部分,避免外界非平板部分干扰
串口通信用的ttyUSB0口,直接一根数据线和stm32的串口1相连就可以了
连接屏幕可以展示效果,但也许有时候展示效果会耗时,建议到时候注释掉展示部分

#获取圆圈坐标并用串口通信将坐标r送到stm32进行处理
# -*- coding: utf-8 -*
import serial
import time
import cv2 
import numpy as np

cap = cv2.VideoCapture(0)
lower_red=np.array([156,43,46])
upper_red=np.array([180,255,255])

def DisBall(x,y,r,frame):
    cv2.circle(frame, (x,y) , r , (0, 255, 0), 2)
    cv2.circle(frame, (x,y) , 2 , (0, 0, 255), 3)
    return frame

def Binary_Get_Ball(frame,show,area,thr):
    cropped = frame[area[0]:area[1], area[2]:area[3]]  #(上,下)(左,右)
    gray_img = cv2.cvtColor(cropped, cv2.COLOR_BGRA2GRAY)#图像灰度化
    ret,thresh=cv2.threshold(gray_img,thr[0],thr[1],cv2.THRESH_BINARY)
    thresh=255-thresh

    cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]  #轮廓检测
    #如果存在轮廓  
    if len(cnts) > 0:  
        #找到面积最大的轮廓  
        c = max(cnts, key = cv2.contourArea)  
        #确定面积最大的轮廓的外接圆  
        ((center_x, center_y), radius) = cv2.minEnclosingCircle(c)  
        if (show==True): 
            cv2.circle(cropped, (int(center_x), int(center_y)), int(radius), (0, 255, 255), 2)  
            cv2.circle(cropped, None, 5, (0, 0, 255), -1)
        print('红色色块的中心坐标',(int(center_x),int(center_y)))
    else:
        center_x=0
        center_y=0
        radius=0
    return center_x,center_y,radius,cropped

if __name__=="__main__":
    # 打开串口
    ser = serial.Serial("/dev/ttyUSB0", 9600, timeout=0.2)
    #剪切区域(上,下)(左,右)
    area=[40,435,155,540]
    #二值化阈值
    thr=[80,255]

    time1=time.time()
    while(1):
        ret, frame = cap.read()
        #得到小球坐标
        x,y,r,frame=Binary_Get_Ball(frame,show=True,area=area,thr=thr)

        time_change=time.time()-time1
        time_change=int(time_change*1000)
        print('time:'+str(time_change).rjust(3,'0'))

        #展示画圆效果
        x=int(x)
        y=int(y)
        r=int(r)
        frame = DisBall(x,y,r,frame)

        send_data='#'+str(x).rjust(3,'0')+str(y).rjust(3,'0')+str(time_change).rjust(3,'0') #起始标志'#',圆心的x和y
        ser.write(send_data.encode("utf8"))
        print(send_data)
        if (x==0 and y==0 and r==0):
            pass
        else:
            time1=time.time()

        # 展示图片
        cv2.imshow("capture", frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            # 存储图片
            cv2.imwrite("camera.jpg", frame)
            break

    if ser != None:
        ser.close()
    cap.release()
cv2.destroyAllWindows()

发挥题其他:追光者(追踪红色激光)

#获取圆圈坐标并用串口通信将坐标r送到stm32进行处理
# -*- coding: utf-8 -*
import serial
import time
import cv2 
import numpy as np

cap = cv2.VideoCapture(0)
lower_red=np.array([156,43,46])
upper_red=np.array([180,255,255])

def DisBall(x,y,r,frame):
    cv2.circle(frame, (x,y) , r , (0, 255, 0), 2)
    cv2.circle(frame, (x,y) , 2 , (0, 0, 255), 3)
    return frame

def Binary_Get_Point(frame,show,area,thr,thr1):
    cropped = frame[area[0]:area[1], area[2]:area[3]]  #(上,下)(左,右)
    gray_img = cv2.cvtColor(cropped, cv2.COLOR_BGRA2GRAY)#图像灰度化
    ret,thresh=cv2.threshold(gray_img,thr[0],thr[1],cv2.THRESH_BINARY)
    ret,thresh1=cv2.threshold(gray_img,thr1[0],thr1[1],cv2.THRESH_BINARY)
    thresh=255-thresh

    cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]  #轮廓检测
    cnts1 = cv2.findContours(thresh1.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]  #轮廓检测
    #如果存在轮廓  
    if len(cnts) > 0:  
        #找到面积最大的轮廓  
        c = max(cnts, key = cv2.contourArea)  
        #确定面积最大的轮廓的外接圆  
        ((center_x, center_y), radius) = cv2.minEnclosingCircle(c)  
        if (show==True): 
            cv2.circle(cropped, (int(center_x), int(center_y)), int(radius), (0, 255, 255), 2)  
            cv2.circle(cropped, None, 5, (0, 0, 255), -1)
        print('小球的中心坐标',(int(center_x),int(center_y)))
    else:
        center_x=0
        center_y=0
        radius=0
    #如果存在轮廓  
    if len(cnts1) > 0:  
        #找到面积最大的轮廓  
        c1 = max(cnts1, key = cv2.contourArea)  
        #确定面积最大的轮廓的外接圆  
        ((center_x1, center_y1), radius1) = cv2.minEnclosingCircle(c1)  
        if (show==True): 
            cv2.circle(cropped, (int(center_x1), int(center_y1)), int(radius1), (0, 255, 255), 2)  
            cv2.circle(cropped, None, 5, (0, 0, 255), -1)
        print('激光的坐标',(int(center_x1),int(center_y1)))
    else:
        center_x1=0
        center_y1=0
        radius1=0
    return center_x,center_y,radius,center_x1,center_y1,radius1,cropped

if __name__=="__main__":
    # 打开串口
    ser = serial.Serial("/dev/ttyUSB0", 9600, timeout=0.2)
    #剪切区域(上,下)(左,右)
    area=[40,435,155,540]
    #二值化阈值
    thr=[80,255]
    thr1=[200,255]

    time1=time.time()
    while(1):
        ret, frame = cap.read()
        x,y,r,x1,y1,r1,frame=Binary_Get_Point(frame,show=True,area=area,thr=thr,thr1=thr1)
            

        time_change=time.time()-time1
        time_change=int(time_change*1000)
        print('time:'+str(time_change).rjust(3,'0'))

        #展示画圆效果
        x=int(x)
        y=int(y)
        r=int(r)
        x1=int(x1)
        y1=int(y1)
        r1=int(r1)

        frame = DisBall(x,y,r,frame)
        frame = DisBall(x1,y1,r1,frame)

        send_data='#'+str(x).rjust(3,'0')+str(y).rjust(3,'0')+str(time_change).rjust(3,'0') #起始标志'#',圆心的x和y
        ser.write(send_data.encode("utf8"))
        print(send_data)
        send_data='$'+str(x1).rjust(3,'0')+str(y1).rjust(3,'0')+str(time_change).rjust(3,'0')
        ser.write(send_data.encode("utf8"))   
        print(send_data)     

        if (x==0 and y==0 and r==0):
            pass
        else:
            time1=time.time()        
        # 展示图片
        cv2.imshow("capture", frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            # 存储图片
            cv2.imwrite("camera.jpg", frame)
            break

    if ser != None:
        ser.close()
    cap.release()
cv2.destroyAllWindows()
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

꧁memorial꧂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值