Solution Details
Drawing dials
There are only 60 minute/second markers and 12 hour markers on the dial, and of course the outer contour circle of the dial, which means the focus is on how to draw the 72 lines. Let's start by drawing the simple circle:
import cv2 as cv import math import datetime import numpy as np margin = 5 # Top, bottom, left and right margins radius = 220 # Radius of a circle center = (center_x, center_y) = (225, 225) # Center of the circle # 1. Create a new palette and fill it with white. img = ((450, 450, 3), np.uint8) img[:] = (255, 255, 255) # 2. Draw the disk (img, center, radius, (0, 0, 0), thickness=5)
When we use OpenCV to draw a straight line, we need to know the coordinates of the starting point and the end point of the line, so drawing 72 lines becomes getting 72 sets of coordinates.
In a plane coordinate system, the coordinates of point A can be expressed as if the radius and angle are known:
x=r×cosα
y=r×sinα
Considering first only moving the origin of the coordinate system to the upper left corner, with the angle still calculated counterclockwise in the planar coordinate system, the new coordinates are:
x=r+r×cosα
y=r+r×sinα
For the 60 minutes / seconds engraved line, the angle between the engraved line is 360 ° / 60 = 6 °, for the hourly engraved line, the angle is 360 ° / 12 = 30 °, so that the 72 sets of starting point coordinates, then how to get the end point coordinates? In fact, the same principle, using a small concentric circle to calculate to get the B point:
A straight line can be drawn through the points A/B:
pt1 = [] # 3. Draw 60 ticks of seconds and minutes. for i in range(60): # Outermost circle, calculate point A x1 = center_x+(radius-margin)*(i*6*/180.0) y1 = center_y+(radius-margin)*(i*6*/180.0) ((int(x1), int(y1))) # Concentric circles, calculate point B x2 = center_x+(radius-15)*(i*6*/180.0) y2 = center_y+(radius-15)*(i*6*/180.0) (img, pt1[i], (int(x2), int(y2)), (0, 0, 0), thickness=2) # 4. Drawing 12 hourly ticks for i in range(12): # 12 hourly ticks should be longer # x = center_x+(radius-25)*(i*30*/180.0) y = center_y+(radius-25)*(i*30*/180.0) # Here's where the previous pt1 is used # (img, pt1[i*5], (int(x), int(y)), (0, 0, 0), thickness=5) # By this point the basic dial diagram has been drawn up
angular conversion
The next is a little difficult, first of all, the starting coordinates of the clock in the direction of 90 ° of the normal two-dimensional coordinate system, and secondly, the clock, like the image, are clockwise calculation of the angle, so the three need to be unified under:
Because the angle is completely symmetrical, clockwise and counterclockwise have no effect, so the plane coordinate system is completely ignored, put here just to facilitate your understanding. For clock and image coordinates, 0° of clock 0 corresponds to 270° of the image, 90° of clock 15 corresponds to 360° of the image, 180° of clock 30 corresponds to 450° of the image (360° + 90°)...
So the relationship between the two is:
Calculated Angle = Clock Angle + 270°
Calculated Angle = Calculated Angle if Calculated Angle<=360° else Calculated Angle-360°
synchronous time
Python how to get the current time and add date text are relatively simple, see the code on the line, I will not explain.
while(1): # Keep copying the dial map in order to update the drawing, otherwise it will overlap temp = (img) # 5. Get the system time and draw the dynamic hour-minute-second triple ticks. now_time = () hour, minute, second = now_time.hour, now_time.minute, now_time.second # Drawing second lines # See the blog, angles are calculated clockwise in OpenCV, so you need to convert them! sec_angle = second*6+270 if second <= 15 else (second-15)*6 sec_x = center_x+(radius-margin)*(sec_angle*/180.0) sec_y = center_y+(radius-margin)*(sec_angle*/180.0) (temp, center, (int(sec_x), int(sec_y)), (255, 0, 0), 2) # Drawing of the quartering line min_angle = minute*6+270 if minute <= 15 else (minute-15)*6 min_x = center_x+(radius-35)*(min_angle*/180.0) min_y = center_y+(radius-35)*(min_angle*/180.0) (temp, center, (int(min_x), int(min_y)), (0, 255, 0), 8) # Drawing the moment line hour_angle = hour*30+270 if hour <= 3 else (hour-3)*30 hour_x = center_x+(radius-75)*(hour_angle*/180.0) hour_y = center_y+(radius-75)*(hour_angle*/180.0) (temp, center, (int(hour_x), int(hour_y)), (0, 0, 255), 20) # 6. Add current date text font = cv.FONT_HERSHEY_SIMPLEX time_str = now_time.strftime("%d/%m/%Y") (img, time_str, (135, 275), font, 1, (0, 0, 0), 2) ('clocking', temp) if (1) == 27: # Press ESC to exit break
The above is python based on opencv to realize the details of the image clock, more information about python opencv to realize the image clock please pay attention to my other related articles!