微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用opencv python

如何解决使用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()

This is the sample clock image used

解决方法

考虑到您检索小时和分钟值的方法是成功的,这里有一个简单的解决方案来查找秒值。
有一些与时钟图像的二手相关联的属性,在估计其价值之前需要做一些准备。第一个是颜色。因为手是红色的,所以你有一个很好的引导点,将它与图像的其余部分分开。如果您可以使用 cv2.inRange() 函数掩盖图像中二手的红色(阅读更多相关信息 here),您将得到一个干净的只有二手图像。之后,您可以使用 cv2.cvtColor() 函数将其转换为黑白。现在,第二个问题可能是二手的细线。您可以使用 Morphological Transformations 解决该问题。使用 Erosion_ 功能,您可以扩大图像的白色区域并加厚二手图像。之后,使用您使用的任何方法来找到分针和时针的值,您就可以开始了。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。