Я использую форму opencv python для преобразования аналоговых часов в цифровые данные для часов и минут, но мне нужно, чтобы они отображались и в течение секунд.

Я использовал opencv, чтобы прочитать изображение, преобразовать его в оттенки серого и найти края, используя canny, kernel, thesh, erode и т. д., и я обнаружил все линии на изображении с помощью HooughLineP(), и я обнаружил часы и минутная стрелка, но мне также нужно найти секундную стрелку, вот код, который я использовал

import cv2
import math
import numpy as np
from matplotlib import pyplot as plt
from math import sqrt
from math import acos, degrees


kernel = np.ones((5,5),np.uint8)
img1 = cv2.imread('input1.jpg')
img = cv2.imread('input1.jpg',0)
gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)

ret, thresh = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY)

# Create mask
height,width = img.shape
#height=height-10
#width=width-10
mask = np.zeros((height,width), np.uint8)

edges = cv2.Canny(thresh, 100, 200)

#cv2.imshow('detected ',gray)
cimg=cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1.2, 100)
#circles = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, 1.2, 1000, param1 = 50, param2 = 30, minRadius = 20, maxRadius = 0)
for i in circles[0,:]:
    i[2]=i[2]+4
    # Draw on mask
    cv2.circle(mask,(i[0],i[1]),i[2],(255,255,255),thickness=-1)

# Copy that image using that mask
masked_data = cv2.bitwise_and(img1, img1, mask=mask)

# Apply Threshold
_,thresh = cv2.threshold(mask,1,255,cv2.THRESH_BINARY)
# Find Contour
contours = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
x,y,w,h = cv2.boundingRect(contours[0])

# Crop masked_data
crop = masked_data[y+30:y+h-30,x+30:x+w-30]
i=crop
height, width, channels = i.shape
print (width, height, channels)
#########################################################################

ret, mask = cv2.threshold(i, 10, 255, cv2.THRESH_BINARY)
edges = cv2.Canny(i,100,200)
kernel = np.ones((11,11),np.uint8)
kernel2 = np.ones((13,13),np.uint8)
edges = cv2.dilate(edges,kernel,iterations = 1)
edges = cv2.erode(edges,kernel2,iterations = 1)
minLineLength = 1000
maxLineGap = 10
lines = cv2.HoughLinesP(edges,1,np.pi/180,15,minLineLength,maxLineGap)
h=[]
xmax1=0
xmax2=0
ymax1=0
ymax2=0
xs1=0
xs2=0
ys1=0
ys2=0

for line in lines:
    x1, y1, x2, y2 = line[0]
    #cv2.line(i, (x1, y1), (x2, y2), (0, 255, 0), 1)
    dx=x2-x1
    if(dx<0):
        dx=dx*-1
    dy=y2-y1
    if(dy<0):
        dy=dy*-1
        
    hypo=sqrt(dx**2 + dy**2)
    
            
    #print("dx=",dx,"  dy=",dy)
    h.append(hypo)

#print(h)
print(len(h))
a=len(h)
h.sort(reverse=True)
#print(h)
m=0
k=0

for f in range(a):
    for line in lines:
        x1, y1, x2, y2 = line[0]
        #cv2.line(i, (x1, y1), (x2, y2), (0, 255, 0), 3)
        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==h[0]):
            m=hypo2
            xmax1=x1
            xmax2=x2
            ymax1=y1
            ymax2=y2
            cv2.line(crop, (xmax1, ymax1), (xmax2, ymax2), (255, 0, 0), 3)
            #print("xmax1=",xmax1," ymax1=",ymax1," xmax2=",xmax2," ymax2=",ymax2)

        if(m==h[0]): 
            if(hypo2==h[f]):
                if((sqrt((xmax2-x2)**2 + (ymax2-y2)**2))>20):
                    if((sqrt((xmax1-x1)**2 + (ymax1-y1)**2))>20):
                        xs1=x1
                        xs2=x2
                        ys1=y1
                        ys2=y2
                        cv2.line(crop, (xs1, ys1), (xs2, ys2), (0, 255, 0), 3)
                        print("xs1=",xs1," ys1=",ys1," xs2=",xs2," ys2=",ys2)
                        k=1
                        break
    if(k==1):                
        break           

print("xmax1=",xmax1," ymax1=",ymax1," xmax2=",xmax2," ymax2=",ymax2)

Я разделил минутную стрелку и часовую стрелку в приведенной выше строке кода, но мне также нужно разделить секундную стрелку. Пожалуйста, помогите мне с этим!

Нажмите здесь, чтобы просмотреть образец входного изображения


person Ajay    schedule 25.06.2021    source источник
comment
Может быть, вы также можете предоставить исходное изображение, чтобы мы могли воспроизвести ваши результаты...   -  person stateMachine    schedule 25.06.2021
comment
Да, теперь я добавил изображение, пожалуйста, помогите мне с ним. Хотел бы я поделиться ссылкой на колаб, с которой я работал до сих пор.   -  person Ajay    schedule 25.06.2021
comment
связанные: forum.opencv.org/t/reading-analog- часы с использованием opencv/4034   -  person Christoph Rackwitz    schedule 26.06.2021


Ответы (1)


На основе этого сообщения: Как обнаружить строки в OpenCV? Я адаптировался с помощью ваше изображение и ваш метод обрезки, он дает действительный вывод данного изображения:

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


kernel = np.ones((5,5),np.uint8)
img1 = cv2.imread('clock.jpg')
img = cv2.imread('clock.jpg',0)
gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)

ret, thresh = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY)

# Create mask
height,width = img.shape
mask = np.zeros((height,width), np.uint8)
edges = cv2.Canny(thresh, 100, 200)

#cv2.imshow('detected ',gray)
cimg=cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1.2, 100)
for i in circles[0,:]:
    i[2]=i[2]+4
    # Draw on mask
    cv2.circle(mask,(i[0],i[1]),i[2],(255,255,255),thickness=-1)

# Copy that image using that mask
masked_data = cv2.bitwise_and(img1, img1, mask=mask)

# Apply Threshold
_,thresh = cv2.threshold(mask,1,255,cv2.THRESH_BINARY)
# Find Contour
contours, hierarchy = 
cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
x,y,w,h = cv2.boundingRect(contours[0])

# Crop masked_data
crop = masked_data[y+30:y+h-30,x+30:x+w-30]


################################
kernel_size = 5
blur_crop = cv2.GaussianBlur(crop,(kernel_size, kernel_size),0)
low_threshold = 50
high_threshold = 150
edges = cv2.Canny(blur_crop, low_threshold, high_threshold)

rho = 1                     # distance resolution in pixels
theta = np.pi / 180         # angular resolution in radians
threshold = 15              # minimum number of votes 
min_line_length = 100       # minimum number of pixels making up a line
max_line_gap = 10           # maximum gap in pixels between connectable 
line segments
line_image = np.copy(crop) * 0 

# Run Hough on edge detected image
# Output "lines" is an array containing endpoints of detected line
lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]),
                    min_line_length, max_line_gap)

for line in lines:
    for x1,y1,x2,y2 in line:
        cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),5)

# Draw the lines on the  image
lines_edges = cv2.addWeighted(crop, 0.8, line_image, 1, 0)

cv2.imshow('line_image', line_image)
cv2.imshow('crop', crop)

С некоторой настройкой параметров обнаружения Хафа вы сможете уменьшить результаты до 3 хороших линий. введите здесь описание изображения

person Tiphel    schedule 25.06.2021
comment
Спасибо за ответ, но мне нужно отделить только секундную стрелку, не могли бы вы помочь мне с этим, пожалуйста? - person Ajay; 25.06.2021
comment
В настоящее время я работаю над этим, может ли кто-нибудь присоединиться ко мне и помочь в этом проекте. Вот ссылка на colab, где вы можете найти меня работающим, пожалуйста, помогите мне с этим. colab.research.google.com/drive/ - person Ajay; 25.06.2021
comment
Итак, вы хотите найти более тонкую линию. Если время обработки не является проблемой, вы можете применить множественную морфологию эрозии перед преобразованием Хафа. Начните с высокого значения эрозии и постепенно уменьшайте его. Основываясь на толщине каждой стрелки, вы знаете, что первая обнаруженная линия — это часовая стрелка, а третья — секундная стрелка. - person Tiphel; 25.06.2021
comment
Я не могу этого понять. Можете ли вы решить ее и отправить мне. У меня также есть ссылка на colab, где я работаю над этой проблемой. - person Ajay; 25.06.2021
comment
Я обновил свой код здесь Для обновленного кода, пожалуйста, ознакомьтесь с кодом. Моя основная проблема в том, что я не знаю, как отделить секундную стрелку от других стрелок, например, в моем коде я использовал 2 цикла for, во втором вложенном цикле for у меня есть разделил x1, x2, y2, y2, согласованные как с минутами, так и с часами, но я не знаю, как получить, таким образом, x1, x2, y1, y2 для секундной стрелки. Пожалуйста, я новичок в этом opencv. это и помоги мне с этим @Tiphel - person Ajay; 26.06.2021