美文网首页
python-opencv-寻找不同颜色圆形以及连线、标记轮廓和

python-opencv-寻找不同颜色圆形以及连线、标记轮廓和

作者: woniuxia | 来源:发表于2020-06-24 09:28 被阅读0次
    • 工具
      win10+python3.8 + opencv-python

    • 功能说明
      1、分别寻找红色和绿色圆形
      2、标记圆心和轮廓
      3、连接两个红色圆形和绿色圆形
      4、以红色圆形位置为基准点,移动绿色圆形移动到红色圆形位置

    • 涉及到函数
      1、寻找圆形
      2、绘制直线
      3、计算夹角
      4、计算偏移量
      5、旋转图片和偏移图片

    • 具体代码如下:

    # -*- coding:utf-8 -*-
    """
    File Name: pro_1
    Author: 82405
    Data: 2020/6/23 10:39
    -----------------------
    Info:
    
    -----------------------
    Change Activity:
        2020/6/23: create
    """
    import logging
    import math
    import numpy as np
    import cv2
    
    logger = logging.getLogger(__file__)
    
    
    def angle(red_line, green_line):
        """
        计算两条直线夹角
        :param red_line:
        :param green_line:
        :return:
        """
        if red_line[0][0] < red_line[1][0]:
            v1 = [red_line[0][0], 0 - red_line[0][1], red_line[1][0], 0 - red_line[1][1]]
        else:
            v1 = [red_line[1][0], 0 - red_line[1][1], red_line[0][0], 0 - red_line[0][1]]
    
        if green_line[0][0] < green_line[1][0]:
            v2 = [green_line[0][0], 0 - green_line[0][1], green_line[1][0], 0 - green_line[1][1]]
        else:
            v2 = [green_line[1][0], 0 - green_line[1][1], green_line[0][0], 0 - green_line[0][1]]
        dx1 = v1[2] - v1[0]
        dy1 = v1[3] - v1[1]
        dx2 = v2[2] - v2[0]
        dy2 = v2[3] - v2[1]
        angle1 = math.atan2(dy1, dx1)
        angle1 = int(angle1 * 180 / math.pi)
        # print(angle1)
        angle2 = math.atan2(dy2, dx2)
        angle2 = int(angle2 * 180 / math.pi)
        # print(angle2)
        if angle1 * angle2 >= 0:
            included_angle = abs(angle1 - angle2)
        else:
            included_angle = abs(angle1) + abs(angle2)
            if included_angle > 180:
                included_angle = 360 - included_angle
        return included_angle
    
    
    def cal_offset(red_line, green_line):
        """
        计算偏移量
        :param red_line:
        :param green_line:
        :return:
        """
        if red_line[0][0] < red_line[1][0]:
            red_left_p = red_line[0]
        else:
            red_left_p = red_line[1]
        if green_line[0][0] < green_line[1][0]:
            green_left_p = green_line[0]
        else:
            green_left_p = green_line[1]
        print(int(red_left_p[0]) - int(green_left_p[0]), int(red_left_p[1]) - int(green_left_p[1]))
        return np.float32(
            [[1, 0, int(red_left_p[0]) - int(green_left_p[0])], [0, 1, int(red_left_p[1]) - int(green_left_p[1])]])
    
    
    planets = cv2.imread('lh_002.jpg')
    # print(planets.shape)
    rows, cols, w = planets.shape
    gray_img = cv2.cvtColor(planets, cv2.COLOR_BGR2GRAY)
    img = cv2.medianBlur(gray_img, 5)
    cimg = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
    
    # 圆形寻找
    circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 120, param1=100, param2=30, minRadius=0, maxRadius=0)
    
    circles = np.uint16(np.around(circles))
    
    red_point = []  # 红色点
    green_point = []  # 绿色点
    
    for i in circles[0, :]:
        # print(i)
        if i[2] > 50:
            continue
        px = planets[i[1], i[0]]    # 获取该像素的RGB值
        # print('坐标[{}, {}]RGB{}'.format(i[1], i[0], px))
        if px[1] > 200 and px[2] < 200:  # 判断红绿
            print('绿色圆圈 绘制红色')
            cv2.circle(planets, (i[0], i[1]), 50, (0, 0, 255), 2)  # 绘制圆形轮廓
            cv2.circle(planets, (i[0], i[1]), 2, (0, 0, 255), 3)  # 绘制圆形圆心
            green_point.append((i[0], i[1]))
        else:
            print('红色圆圈 绘制绿色')
            cv2.circle(planets, (i[0], i[1]), 50, (0, 255, 0), 2)  # 绘制圆形轮廓
            cv2.circle(planets, (i[0], i[1]), 2, (0, 255, 0), 3)  # 绘制圆形圆心
            red_point.append((i[0], i[1]))
    
    # cv2.imwrite('lh_000.jpg', planets)
    print(red_point)
    print(green_point)
    cv2.line(planets, red_point[0], red_point[1], (255, 0, 0), 2)
    cv2.line(planets, green_point[0], green_point[1], (255, 0, 0), 2)
    angle_val = angle(red_point, green_point)  # 计算夹角
    mat_translation = cal_offset(red_point, green_point)  # 计算偏移量
    if green_point[0][0] > green_point[1][0]:  # 判断绿线定位点 去x轴值小的那个点
        M = cv2.getRotationMatrix2D(green_point[1], 0 - angle_val, 1)  # 旋转
    else:
        M = cv2.getRotationMatrix2D(green_point[0], 0 - angle_val, 1)  # 旋转
    dst = cv2.warpAffine(planets, M, (cols, rows))  # 旋转
    dst = cv2.warpAffine(dst, mat_translation, (cols, rows))  # 偏移
    
    cv2.namedWindow('image', cv2.WINDOW_NORMAL)
    cv2.namedWindow('image_dist', cv2.WINDOW_NORMAL)
    cv2.imshow('image', planets)
    cv2.imshow('image_dist', dst)
    cv2.waitKey()
    cv2.destroyAllWindows()
    
    
    • 原图


      lh_002.jpg
    • 最终效果图


      image.png

    相关文章

      网友评论

          本文标题:python-opencv-寻找不同颜色圆形以及连线、标记轮廓和

          本文链接:https://www.haomeiwen.com/subject/gdglfktx.html