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

  • 工具
    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()

  • 原图
    python-opencv-寻找不同颜色圆形以及连线、标记轮廓和圆心_第1张图片

  • 最终效果图
    python-opencv-寻找不同颜色圆形以及连线、标记轮廓和圆心_第2张图片

你可能感兴趣的:(openCv,python)