如何解决使用opencv python
我尝试使用opencv python读取模拟时钟图像并使用数字图像显示时间,我已经通过使用opencv使用HoughLineP()将小时和分针与图像分开来读取小时和分钟,但是我无法从图像中分离秒针,这是我正在使用的代码请帮我分离秒针并读取秒值>
import cv2
import math
import numpy as np
import matplotlib.pyplot as plt.
from math import sqrt,acos,degrees
import tkinter as tk
kernel = np.ones((5,5),np.uint8)
img = cv2.imread('input3.jpg')
ret,thresh = cv2.threshold(gray_img,50,255,cv2.THRESH_BINARY)
height,width = gray_img.shape
mask = np.zeros((height,width),np.uint8)
edges = cv2.Canny(thresh,100,200)
cimg=cv2.cvtColor(gray_img,cv2.COLOR_GRAY2BGR)
circles = cv2.HoughCircles(gray_img,cv2.HOUGH_GRADIENT,1.2,100)
for i in circles[0,:]:
# print(i) # -> [429.00003 240.6 226.20001]
i[2] = i[2] + 4
# used to detect the circle in the image
cv2.circle(mask,(int(i[0]),int(i[1])),int(i[2]),(255,255),thickness=-1)
masked_data = cv2.bitwise_and(img,img,mask=mask)
_,thresh = cv2.threshold(mask,1,cv2.THRESH_BINARY)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
# Crop masked_data
crop = masked_data[y + 30 : y + h - 30,x + 30 : x + w - 30
i=crop
height,width,channels = i.shape
ret,mask = cv2.threshold(i,10,cv2.THRESH_BINARY)
edges = cv2.Canny(i,200)
kernel = np.ones((11,11),np.uint8)
kernel1 = np.ones((13,13),np.uint8)
edges = cv2.dilate(edges,kernel,iterations = 1)
edges = cv2.erode(edges,kernel1,iterations = 1)
minLineLength = 1000
maxLineGap = 10
lines = cv2.houghlinesp(edges,np.pi/180,15,minLineLength,maxLineGap)
l=[]
# l -> long,s -> short
xl1,xl2,yl1,yl2 = 0,0
xs1,xs2,ys1,ys2=0,0
for line in lines:
# getting the values from the line
x1,y1,x2,y2 = line[0]
dx = x2 - x1
if(dx<0):
dx = dx * -1
dy = y2 - y1
if(dy < 0):
dy = dy * -1
hypo = sqrt(dx ** 2 + dy ** 2 )
l.append(hypo)
a=len(l) # -> 295
l.sort(reverse=True)
m=0
h=0
for f in range(a):
for line in lines:
# getting the values from the line
x1,y2 = line[0]
dx = x2 - x1
if(dx < 0):
dx = dx * -1
dy = y2 - y1
if(dy < 0):
dy = dy * -1
hypo2 = sqrt(dx ** 2 + dy ** 2 )
if(hypo2 == l[0]):
m = hypo2
xl1 = x1
xl2 = x2
yl1 = y1
yl2 = y2
# getting line region
cv2.line(crop,(xl1,yl1),(xl2,yl2),0),3)
if(m==l[0]):
if(hypo2 ==l[f]):
if((sqrt((xl2 - x2)**2 + (yl2 - y2)**2)) > 20):
if((sqrt((xl1 - x1)**2 + (yl1 - y1)**2))>20):
xs1 = x1
xs2 = x2
ys1 = y1
ys2 = y2
# getting line region
cv2.line(crop,(xs1,ys1),(xs2,ys2),(0,3)
h=1
break
if(h==1):
break
xcenter = int(width / 2)
ycenter = int(height / 2)
hour1 = abs(xcenter - xs1)
hour2 = abs(xcenter - xs2)
if(hour1 > hour2):
xhour = xs1
yhour = ys1
else:
xhour = xs2
yhour = ys2
min1 = abs(xcenter - xl1)
min2 = abs(xcenter - xl2)
if(min1 > min2):
xmin = xl1
ymin = yl1
else:
xmin = xl2
ymin = yl2
l1 = sqrt( ((xcenter - xhour) ** 2) + ((ycenter - yhour) ** 2) )
l2 = ycenter
l3 = sqrt( ((xcenter - xhour) ** 2) + ((0 - yhour) ** 2) )
cos_theta_hour = ( ( (l1) ** 2 ) + ( (l2) ** 2 ) - ( (l3) ** 2) ) / ( 2 * (l1) * (l2) )
theta_hours_radian = acos(cos_theta_hour)
theta_hours = math.degrees(theta_hours_radian)
if(xhour > xcenter):
right=1
else:
right=0
if(right==1):
hour = int(theta_hours / (6*5))
if(right==0):
hour = 12 - (int(theta_hours / (6*5)))
if(hour==0):
hour=12
l1 = sqrt( ((xcenter - xmin) ** 2) + ((ycenter - ymin) ** 2) )
l2 = ycenter
l3 = sqrt( ((xcenter - xmin) ** 2) + ((0 - ymin) ** 2) )
cos_theta_min = ( ( (l1) ** 2 ) + ( (l2) ** 2 ) - ( (l3) ** 2) ) / ( 2 * (l1) * (l2) )
theta_min_radian = acos(cos_theta_min)
theta_min = math.degrees(theta_min_radian)
if(xmin > xcenter):
right=1
else:
right=0
if(right==1):
minute = int(theta_min / ((6*5)/5))
if(right==0):
minute = 60 - (int(theta_min / ((6*5)/5)))
if(xmin == xcenter):
minutes=30
if (minute < 10):
def display():
value = "{}:0{}".format(hour,minute)
digit.config(text = value)
else:
def display():
value = "{}:{}".format(hour,minute)
digit.config(text = value)
canvas = tk.Tk()
canvas.title("Analog to Digital")
canvas.geometry("300x250")
digit = tk.Label(canvas,font=("ds-digital",65,"bold"),bg="black",fg="blue",bd = 80)
digit.grid(row=0,column = 1)
display()
canvas.mainloop()
解决方法
考虑到您检索小时和分钟值的方法是成功的,这里有一个简单的解决方案来查找秒值。
有一些与时钟图像的二手相关联的属性,在估计其价值之前需要做一些准备。第一个是颜色。因为手是红色的,所以你有一个很好的引导点,将它与图像的其余部分分开。如果您可以使用 cv2.inRange()
函数掩盖图像中二手的红色(阅读更多相关信息 here),您将得到一个干净的只有二手图像。之后,您可以使用 cv2.cvtColor()
函数将其转换为黑白。现在,第二个问题可能是二手的细线。您可以使用 Morphological Transformations 解决该问题。使用 Erosion_ 功能,您可以扩大图像的白色区域并加厚二手图像。之后,使用您使用的任何方法来找到分针和时针的值,您就可以开始了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。