滚球控制系统视觉部分代码-Python

2017年电赛控制方向,视觉部分,Python写的。
处理设备:Jetson Nano
摄像头:KS1A552,100万像素,镜头2.4mm焦距。

import cv2          #cv2读取的格式是BGR
import numpy as np
import time
import serial

serial_port = serial.Serial(
    port="/dev/ttyTHS1",   #这里注意一下这个端口号,使用前要赋予串口权限:sudo chmod 777 /dev/ttyTHS1
    baudrate=115200,
    bytesize=serial.EIGHTBITS,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
)
# Wait a second to let the port initialize
time.sleep(1)

# 角点检测
def harris(image):
    blockSize = 5
    apertureSize = 3
    k = 0.06
    gray = np.float32(image)
    T = (0.05, 0.01, 0.005)
    for t in T:
        dst = cv2.cornerHarris(gray, blockSize, apertureSize, k)
        a = dst>t*dst.max()
        T = (0.05, 0.01, 0.005)
        for t in T:
            dst = cv2.cornerHarris(gray, blockSize, apertureSize, k)
            a = dst > t * dst.max()
            image[a] = (0, 0, 255)
    dst = cv2.cornerHarris(gray, blockSize, apertureSize, k)
    dst_norm = np.empty(dst.shape, dtype=np.float32)
    cv2.normalize(dst, dst_norm, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX)
    xy = []
    for i in range(dst_norm.shape[0]):
        for j in range(dst_norm.shape[1]):
            if int(dst_norm[i, j]) > 135:  # 120是角点检测阈值
                cv2.circle(image, (j, i), 2, (0, 255, 0), 2)
                xy.append([i, j])
    return image,xy

# 透视变换
def PerspectImage(xy1=[], xy2=[], xy3=[], xy4=[]):
    srcArr = np.float32([xy1[0], xy2[0], xy3[0], xy4[0]])
    dstArr = np.float32([[0, 0], [650, 0], [0, 650], [650, 650]])
    Matrix = cv2.getPerspectiveTransform(srcArr, dstArr)
    # dst = cv2.warpPerspective(image, Matrix,(650,650))  # 转换图片
    return Matrix


# 中值滤波
def midfilter(image):
    img_2 = cv2.medianBlur(image,5)
    return img_2

# 找圆
def findcircles(image,y0,x0,y1,x1):
    image = image[y0+10:y1-10, x0+20:x1-10]
    ret, image_2 = cv2.threshold(image, 220, 255, cv2.THRESH_BINARY)
    """
    # 高斯模糊,降低噪声
    blurred = cv2.GaussianBlur(gray, (3, 3), 0)
    # 图像梯度
    xgrad = cv2.Sobel(blurred, cv2.CV_16SC1, 1, 0)
    ygrad = cv2.Sobel(blurred, cv2.CV_16SC1, 0, 1)
    # 计算边缘
    #     # 50和150参数必须符合1:3或者1:2
    edge_output = cv.Canny(xgrad, ygrad, 50, 150)
    """
    contours, hierarchy = cv2.findContours(image_2, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    global sparecircle
    for i in range(len(contours)):
        cnt = contours[i]
        (x, y), radius = cv2.minEnclosingCircle(cnt)   # 找到最小外接圆
        if (x,y) is None:
            (x, y) = sparecircle
        if radius<12 and radius>7:
            (x, y, radius) = np.int0((x+x0+20, y+y0+10, radius))  # 得到的圆心像素点坐标
            sparecircle = (x, y)
            cv2.drawContours(image, cnt, -1, (0, 0, 255), 2)
            break
    return image, image_2, (x, y), radius


# 矩阵乘法得到圆心在木板上坐标
def matrix(a=[], b=[]):
    point = []
    point.append((a[0][0] * b[0] + a[0][1] * b[1] + a[0][2] * b[2])/(a[2][0] * b[0] + a[2][1] * b[1] + a[2][2] * b[2]))
    point.append((a[1][0] * b[0] + a[1][1] * b[1] + a[1][2] * b[2])/(a[2][0] * b[0] + a[2][1] * b[1] + a[2][2] * b[2]))
    point.append(a[2][0] * b[0] + a[2][1] * b[1] + a[2][2] * b[2])
    return point


xy11 = 0
xy22 = 0
xy33 = 0
xy44 = 0
video = cv2.VideoCapture(1)
video.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
video.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
sparecircle = (294, 116)
while True:
    ret, frame = video.read()
    if ret:
        gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)  # 转成灰度图
        # 角点检测
        cropped1 = gray[0:50, 40:100]
        xy1 = []
        done1, xy1 = harris(cropped1)
        xy1 = [[xy1[0][0] + 40, xy1[0][1]]] + xy1
        if xy1 == None:
            xy1 = xy11
        if xy1!=None:
            xy11 = xy1
        cropped2 = gray[5:60, 470:550]
        xy2 = []
        done2, xy2 = harris(cropped2)
        xy2 = [[xy2[0][0] + 470, xy2[0][1] + 5]] + xy2
        if xy2 == None:
            xy2 = xy22
        if xy2 != None:
            xy22 = xy2
        cropped3 = gray[410:480, 50:110]
        xy3 = []
        done3, xy3 = harris(cropped3)
        xy3 = [[xy3[0][0] + 50, xy3[0][1] + 410]] + xy3
        if xy3 == None:
            xy3 = xy33
        if xy3 != None:
            xy33 = xy3
        cropped4 = gray[410:480, 430:550]
        xy4 = []
        done4, xy4 = harris(cropped4)
        xy4 = [[xy4[0][0] + 430, xy4[0][1] + 410]] + xy4
        if xy4 == None:
            xy4 = xy44
        if xy4!=None:
            xy44 = xy4

        # 获得转换矩阵 Z=[]
        Z = PerspectImage(xy1, xy2, xy3, xy4)
        cen = ()
        img1, img2, cen, rad = findcircles(gray,xy1[0][1], xy1[0][0], xy4[0][1], xy4[0][0])
        print("原圆心坐标:", (cen[0], cen[1]))
        cent = [cen[0], cen[1], 1]
        point = matrix(Z, cent)
        x = cen[0]
        y = cen[1]
        print("圆心坐标:", point)
        # serial_port.write((x+"$"+y+'\r\n').encode())
        # print("serial sent ok")
        cv2.imshow('test',gray)
        # cv2.imshow('test3', img_z)
        cv2.imshow('test2', img2)
        if cv2.waitKey(10) & 0xff == 27:
            break
    else:
        print("摄像头打开失败,请检查")

"""
img = cv2.imread("./4.png")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  # 转成灰度图
cen = ()
img1, img2, cen, rad = findcircles(gray)
print(cen, rad)
cent = [cen[0],cen[1],1]
print(cent, rad)
img4 = np.hstack((gray, img1, img2))  # 第一张是灰度图,第二张是画了圈的灰度图,第三张是二值化
cv2.imshow('result', img4)
cv2.waitKey(0)
cv2.destroyAllWindows()
"""
cv2.destroyAllWindows()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zkisltm

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

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

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

打赏作者

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

抵扣说明:

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

余额充值