Monster 代码,欢迎关注

Monster 代码,欢迎关注

"""
代码见资源
"""
# ################################################初始化##############################
open_once = yaml_handle.get_yaml_data('/boot/camera_setting.yaml')['open_once']
if open_once:
    cap = cv2.VideoCapture('http://127.0.0.1:8080/?action=stream?dummy=param.mjpg')
else:
    cap = Camera.Camera()
    cap.camera_open()
Board.setPWMServoPulse(1, 980, 500)  # NO3机器人,初始云台角度(1号代表上下,2号代表左右)
Board.setPWMServoPulse(2, 1400, 500)
SSR.running_action_group('0', 1)  ##回中
ret = False  # 读取图像标志位
org_img = None  # 全局变量,原始图像
# count=0
c = 0
a = 0
stop = 0
frame_floor_blue = None
frame_show = True
frame_ready = True

stageLeft = {'start_door', 'square_hole', 'bridge',  # #########     剩余关卡
             'cross_obs', 'baffler', 'gate',
             'deadball', 'floor', 'end_door'}
# 获取最大轮廓以及它的面积
ori_width = int(4 * 160)  # 原始图像640x480
ori_height = int(3 * 160)
r_width = int(4 * 20)  # 处理图像时缩小为80x60,加快处理速度,谨慎修改!
r_height = int(3 * 20)
color_range1 = {
    "black": [(0, 0, 0), (65, 255, 255)],
    "yellow": [(0, 120, 140), (255, 255, 255)],
    "red": [(0, 156, 88), (255, 255, 255)],
    "green": [(90, 0, 135), (255, 110, 255)],
    "blue_stair": [(35, 0, 0), (255, 130, 120)],
    "blue_door": [(0, 0, 0), (255, 255, 112)],
    "blue_mine": [(0, 125, 0), (255, 255, 100)],
    "white_door": [(160, 0, 0), (255, 255, 255)],
    "white_road": [(160, 0, 0), (255, 255, 255)],
    "white_mine": [(100, 0, 0), (255, 255, 255)],
    "white_stair": [(193, 0, 0), (255, 255, 255)],
    "white_ball": [(193, 0, 0), (255, 255, 255)],

    "corner_land": [(54, 0, 46), (255, 255, 255)],
}


# ###############################################读取图像线程###########################
def get_img():
    global org_img
    global ret
    global frame_cali
    global cap
    # global orgFrame
    calibration_param_path = "calibration_param0.npz"
    param_data = np.load(calibration_param_path)
    dim = tuple(param_data["dim_array"])
    k = np.array(param_data["k_array"].tolist())
    d = np.array(param_data["d_array"].tolist())
    p = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(k, d, dim, None)
    map = cv2.fisheye.initUndistortRectifyMap(k, d, np.eye(3), p, dim, cv2.CV_16SC2)
    while True:
        ret, org_img = cap.read()
        frame_cali = cv2.remap(
            org_img,
            map[0],
            map[1],
            interpolation=cv2.INTER_LINEAR,
            borderMode=cv2.BORDER_CONSTANT,
        )
        if ret:
            cv2.imshow('img', org_img)
            # orgFrame = cv2.resize(org_img, (ori_width, ori_height),
            # interpolation=cv2.INTER_CUBIC)
            key = cv2.waitKey(1)
            if key == 27:
                break
            else:
                time.sleep(0.01)


# 读取图像线程
th1 = threading.Thread(target=get_img)
th1.setDaemon(True)
th1.start()
"""
org_img = cv2.imread('lei_ground1.png')
cv2.imshow('org_img',org_img)
cv2.waitKey()
cv2.destroyAllWindows()
"""


def end_door_land_percent(type):  # 计算end_door_percent,判断是否走完
    global org_img
    # img = org_img[200:, :]
    r_h = org_img.shape[0]
    r_w = org_img.shape[1]

    gauss = cv2.GaussianBlur(org_img, (3, 3), 0)
    hsv = cv2.cvtColor(gauss, cv2.COLOR_BGR2HSV)
    Imask0 = cv2.inRange(hsv, color_range[type][0],
                         color_range[type][1])
    # opened = cv2.morphologyEx(Imask0, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8))  # 开运算 去噪点
    # closed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, np.ones((3, 3), np.uint8))  # 闭运算 封闭连接
    # erode = cv2.erode(Imask0, None, iterations=1)  # 腐蚀
    dilate = cv2.dilate(Imask0, np.ones((3, 3), np.uint8), iterations=2)  # 膨胀
    try:
        contours, hierarchy = cv2.findContours(dilate, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
        area = getAreaSumContour(contours)
        # percent0 = round(area * 100 / (r_w * r_h), 2)
        areaMaxContour, area_max = getAreaMaxContour(contours)  # 找出最大轮廓
        # cv2.drawContours(org_img, areaMaxContour, -1, (255, 0, 255), 2)
        #cv2.imshow('o', org_img)
        #cv2.waitKey()
        #cv2.destroyAllWindows()
        percent = round(100 * area_max / (r_w * r_h), 2)  # 最大轮廓最小外接矩形的面积占比
        print(f"green_percent = {percent}")
        return percent, 'ok'
    except:
        return 0, 'error'


def end_door_color_detect_top(color, grad=1.0, ksizes=None, defaults=None):

    # 图像处理及roi提取
    # global frame_cali, frame_ready
    # while not frame_ready:
    #     time.sleep(0.01)
    # frame_ready = False
    # frame_cali = cv2.imread("key frame/images/0667.jpg")
    time.sleep(0.5)
    img = frame_cali.copy()
    close = get_frame_bin(img, color, ksizes_[0], ksizes_[1])
    cnts, _ = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

    cnt_max, area_max = getAreaMaxContour(cnts)
    percent = round(100 * area_max / ((close.shape[0]) * (close.shape[1])))  # 计算目标区域占比

    # 得到上顶点,计算中点及线段角度
    if cnt_max is None:
        cnt_max = np.array([[[0, 0]], [[639, 0]], [[639, 479]], [[0, 479]]])
        top_angle, top_center, top_left, top_right = defaults_
    else:
        top_left = cnt_max[0][0]
        top_right = cnt_max[0][0]
        for c in cnt_max:  # 遍历找到四个顶点
            if c[0][0] + grad * c[0][1] < top_left[0] + grad * top_left[1]:
                top_left = c[0]
            if -c[0][0] + grad * c[0][1] < -top_right[0] + grad * top_right[1]:
                top_right = c[0]
        line_top = line(top_left, top_right)
        top_angle = line_top.angle()
        top_center = line_top.mid_point()  # 需要转换成tuple使用
        img_show = img.copy()
        cv2.drawContours(img_show, [cnt_max], -1, (0, 255, 255), 2)
        cv2.circle(img_show, tuple(top_center), 5, (255, 0, 0), 2)
        cv2.circle(img_show, tuple(top_left), 5, (255, 0, 0), 2)
        cv2.circle(img_show, tuple(top_right), 5, (255, 0, 0), 2)
    '''
    cv2.imshow("Result", img_show)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    '''
    return percent, top_angle, [top_center, top_left, top_right]


def end_door_area_sum(type):
    global org_img
    r_w = 160
    r_h = 120
    border = cv2.copyMakeBorder(org_img, 12, 12, 16, 16, borderType=cv2.BORDER_CONSTANT,
                                value=(255, 255, 255))  # 扩展白边,防止边界无法识别
    org_img_copy = cv2.resize(border, (r_w, r_h), interpolation=cv2.INTER_CUBIC)  # 将图片缩放
    frame_gauss = cv2.GaussianBlur(org_img_copy, (3, 3), 0)  # 高斯模糊
    frame_hsv = cv2.cvtColor(frame_gauss, cv2.COLOR_BGR2HSV)  # 将图片转换到HSV空间

    frame_door = cv2.inRange(frame_hsv, color_range[type][0],
                             color_range[type][1])  # 对原图像和掩模(颜色的字典)进行位运算

    opened = cv2.morphologyEx(frame_door, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8))  # 开运算 去噪点
    closed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, np.ones((3, 3), np.uint8))  # 闭运算 封闭连接

    contours, hierarchy = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)  # 找出轮廓
    contour_area_sum = getAreaSumContour(contours)
    print("contour_area_sum:", contour_area_sum)
    return contour_area_sum


def floor_to_end():
    global org_img
    global land_result
    land_result = None
    SSR.running_action_group('stand', 1)
    time.sleep(0.5)
    img = org_img.copy()
    Board.setPWMServoPulse(1, 1200, 500)
    Board.setPWMServoPulse(2, 1450, 500)
    time.sleep(0.5)
    # cv2.imwrite("pi_send_img.jpg", img)
    # land_result = img_land_test()
    land_result = 'end_land'
    print(land_result)
    if land_result == 'end_land':
        cou_ = 5
        # 先前进几步,直到靠近最后的门那里(保持一定的距离,便于再次检测到门打开时,进行冲刺)
        while cou_ is not 0:
            print(f"{cou_}")
            SSR.running_action_group('239new', 1)
            cou_ -= 1
        #print("强行右转2次")
        #SSR.running_action_group('203', 2)
        # for i in range(3):
        #     SSR.running_action_group('203',1)
        #     time.sleep(0.5)
        # 正对且居中
        count = 0
        while True:
            grad = 2.5
            ksizes = [11, 7]
            defaults = [-2, (320, 240), (300, 240), (340, 240)]
            _, angle, points = end_door_color_detect_top(
                "white_road", grad, ksizes, defaults
            )
            center_x, center_y = points[0]
            print(f"angle,center_x, center_y = {angle, center_x, center_y}")
            # 调整角度
            print(f"angle: {angle:.2f}  ({center_x},{center_y})")
            if angle <= -3.5:
                print("右转")
                SSR.running_action_group('turn_right_fast', 1)
                time.sleep(0.2)
            elif angle >= 3:
                print("左转")
                SSR.running_action_group('turn_left_fast', 1)
                time.sleep(0.2)
            else:
                print("正对完成,左移调整")
                # 大步左平移
                if center_x <= 300:
                    print("左移")
                    SSR.running_action_group('left_move_fast', 1)
                elif center_x >= 370:
                    print("右移")
                    SSR.running_action_group('right_move_fast', 1)
                else:
                    SSR.running_action_group('stand', 1)
                    # time.sleep(0.1)
                    count += 1
                    if count >= 2:
                        print("移动到与正前方赛道边缘平行且居中的位置")
                        # for i in range(3):
                        # SSR.running_action_group('232new', 1)
                        # time.sleep(0.2)
                        break

        # print("land_result")
        # 抬头,便于检测地面
        # Board.setPWMServoPulse(1, 1100, 500)  # NO3机器人,初始云台角度(1号代表上下,2号代表左右)
        # Board.setPWMServoPulse(2, 1400, 500)
        # 先前进几步
        # 检测最后的门,如果门还没重新闭合,就等待,直到门重新打开时,立马往前冲过去


def end_door_():
    """
    思路:
    站立,抬头,确定处于end_door这一关卡(利用land_detect+door_area面积,双重判断),
    识别门是否闭合(情况1:闭合;情况2:未闭合)(计算面积)
        当闭合时,识别door面积,判断开启,等待开启
        当未闭合时,等待闭合,进入情况1
    最后在开启时,往前冲,根据地面图纸面积percent,判断何时停下来
    """
    global orgFrame
    global debug
    global org_img
    # global land_result
    type = 'yellow_door'
    end_door_flag = 0
    # 抬头
    Board.setPWMServoPulse(1, 1050, 500)
    Board.setPWMServoPulse(2, 1400, 500)
    time.sleep(0.5)
    end_door_percent_ = end_door_area_sum(type=type)
    # 判断是否处于end_door
    # if end_door_percent_ is not 'error' and land_result == 'end_land':
    if end_door_percent_ is not 'error':
        end_door_flag = 1
        # while True:
        # if end_door_area_sum(type=type) >= 350:
        # 直行
        ## SSR.running_action_group('239new', 1)
        # else:
        #  SSR.running_action_group('stand', 1)

        # while end_door_flag <= 3:

        while end_door_flag == 1:
            # 判断第一次门是否闭合
            print("close or open")
            a = end_door_area_sum(type=type)
            print(f"a = {a}")
            time.sleep(1)
            b = end_door_area_sum(type=type)
            print(f"b = {b}")
            deta = a - b
            print(f"deta = {deta}")
            if deta >= 100:  # 正闭合
                time.sleep(0.5)
                end_door_flag = 4
                
                
            else:  # 没闭合,原地等待
                
                SSR.running_action_group('stand', 1)
                # end_door_flag = 3

        # while end_door_flag == 2:
        #     # 判断门是否闭合
        #     print("close")
        #     if end_door_area_sum(type=type) == 0:  # 开
        #         end_door_flag = 4
        #         break
        #     else:  # 闭合,原地等待
        #         SSR.running_action_group('stand', 1)
        #
        # while end_door_flag == 3:
        #     print('open')
        #     SSR.running_action_group('stand', 1)
        #     if end_door_area_sum(type=type) >= 200:
        #         end_door_flag = 2

    count = 0
    while end_door_flag == 4:
        # 低头
        Board.setPWMServoPulse(1, 950, 500)
        Board.setPWMServoPulse(2, 1400, 500)
        time.sleep(0.5)
        percent, result = end_door_land_percent(type='end_land')
        print(f"percent, result = {percent, result}")
        if result is not 'error':
            if percent >= 20:
                while percent >= 20:
                    # 直行
                    SSR.running_action_group('239new', 1)
                    # end_door_flag = 3

            else:
                count += 1
            if count >= 2:
                SSR.running_action_group('stand', 1)
                print("state:end_door:exit")

def end_door():
    floor_to_end()
    end_door_()

if __name__ == '__main__':
    floor_to_end()
    end_door_()
    # Board.setPWMServoPulse(1, 1200, 500)
    # Board.setPWMServoPulse(2, 1450, 500)
"""
最后的双开合门
未测试
"""
"""
代码见资源
"""

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

QiBenSu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值