opencv+python实现钟表指针度数读取

本程序的思路是:

1.利用模板匹配找到目标图片中的钟表

2. 将目标图片中的钟表截取下来,利用cv2.HoughCircles()把钟表的圆形轮廓,圆半径,圆心识别出来

3.利用cv2.HoughLinesP函数找圆形轮廓中的直线,根据指针与圆心的关系,即过圆心的直线就是钟表指针这个判断条件减小一些误差

4.最后计算得到的直线斜率可知直线的度数,然后可设计一个公式将度数与钟表刻度进行转换(我还没做,做完再更新吧)

注意:

本程序其实极其简陋,精确度极差!!!!!

opencv+python实现钟表指针度数读取_第1张图片

import cv2
import numpy
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('demo/1.jpg')
target = cv2.imread('demo/11.jpg')
th, tw = target.shape[:2]
# 进行模板匹配
result = cv2.matchTemplate(target, img, cv2.TM_SQDIFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
tl = min_loc
br = (tl[0] + tw, tl[1] + th)
# 绘制矩形
cv2.rectangle(img, tl, br, (0, 0, 255), 2)
img = img[tl[1] + 2:tl[1] + th - 2, tl[0] + 2:tl[0] + tw - 2]
grey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 高斯滤波,中值滤波
grey = cv2.GaussianBlur(grey, (3, 3), 0)
# 轮廓检测
_, th = cv2.threshold(grey, 0, 255, cv2.THRESH_TOZERO + cv2.THRESH_OTSU)
edges = cv2.Canny(th, 50, 125)
# 膨胀 腐蚀
# element = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
# edges = cv2.erode(edges, element)
# edges = cv2.dilate(edges, element)
# 找圆
circles1 = cv2.HoughCircles(grey, cv2.HOUGH_GRADIENT, 1, 100, param1=100, param2=30, minRadius=15, maxRadius=80)
circles = circles1[0, :, :]
circles = np.uint16(np.around(circles))
for i in circles[:]:
    cv2.circle(grey, (i[0], i[1]), i[2], (0, 255, 0), 3)  # 画圆
    cv2.circle(grey, (i[0], i[1]), 2, (255, 255, 255), 10)  # 画圆心
minLineLength = 100
maxLineGap = 32
# 找直线
lines = cv2.HoughLinesP(edges, 1.0, np.pi / 180, 20, minLineLength, maxLineGap)
for line in lines:
    for x1, y1, x2, y2 in line:
        if not ((x2 - i[0]) ^ 2 + (y2 - i[1]) ^ 2) > i[2] ^ 2:  # 在圆以外的直线不考虑
            if (x1 - i[0]) / (y1 - i[1]) - (x2 - i[0]) / (y2 - i[1]) <= 1:  # 找与圆心在一条直线上的直线,即尽可能排除指针以外的干扰
                cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 1)
                x1 = float(x1)
                x2 = float(x2)
                y1 = float(y1)
                y2 = float(y2)
                # 计算斜率
                if x2 - x1 == 0:
                    print("直线是竖直的")
                    result = 90
                elif y2 - y1 == 0:
                    print("直线是水平的")
                    result = 0
                else:
                    k = -(y2 - y1) / (x2 - x1)
                    # 求反正切,再将得到的弧度转换为度
                    result = np.arctan(k) * 57.29577
                    print("直线倾斜角度为:" + str(result) + "度")

cv2.namedWindow("img", 0)
cv2.namedWindow("img1", 0)
cv2.imshow("img", edges)
cv2.imshow("img1", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

你可能感兴趣的:(opencv)