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