Python基于OpenCV实现动态图像时钟

慢慢来
慢慢来
发布时间:2026-10-15| 5人浏览过
原创

本文详细介绍如何使用Python和OpenCV库实现一个动态图像时钟。内容涵盖表盘绘制、72根刻线的坐标计算、角度转换逻辑以及实时时间同步更新。通过解析平面坐标系与图像坐标系的转换关系,提供完整的代码实现方案,帮助开发者掌握OpenCV在图形绘制和时间处理方面的应用技巧。

解决方案详解

绘制表盘

表盘设计包含60条分/秒刻线和12条小时刻线,以及外部轮廓圆。核心难点在于如何准确绘制这72根线条。首先,我们需要绘制出基础的圆形轮廓:


import cv2 as cv
import math
import datetime
import numpy as np

margin = 5 # 上下左右边距
radius = 220 # 圆的半径
center = (center_x, center_y) = (225, 225) # 圆心

# 1. 新建一个画板并填充成白色
img = np.zeros((450, 450, 3), np.uint8)
img[:] = (255, 255, 255)

# 2. 画出圆盘
cv.circle(img, center, radius, (0, 0, 0), thickness=5)

使用OpenCV绘制直线需要确定起点和终点的坐标,因此绘制72根线转化为获取72组坐标点的问题。在平面坐标系中,已知半径r和角度α,A点的坐标计算公式为:x=r×cosα,y=r×sinα。

将坐标系原点移至左上角后,角度仍按平面坐标系逆时针计算,新坐标公式为:x=r+r×cosα,y=r+r×sinα。对于60条分/秒刻线,相邻刻线夹角为360°/60=6°;对于小时刻线,角度间隔为360°/12=30°。由此得到72组起点坐标,终点坐标则通过同心小圆计算B点获得:

根据A、B两点坐标即可绘制出直线:


pt1 = []

# 3. 画出60条秒和分钟的刻线
for i in range(60):
  # 最外部圆,计算A点
  x1 = center_x+(radius-margin)*math.cos(i*6*np.pi/180.0)
  y1 = center_y+(radius-margin)*math.sin(i*6*np.pi/180.0)
  pt1.append((int(x1), int(y1)))

  # 同心小圆,计算B点
  x2 = center_x+(radius-15)*math.cos(i*6*np.pi/180.0)
  y2 = center_y+(radius-15)*math.sin(i*6*np.pi/180.0)

  cv.line(img, pt1[i], (int(x2), int(y2)), (0, 0, 0), thickness=2)

# 4. 画出12条小时的刻线
for i in range(12):
  # 12条小时刻线应该更长一点
  x = center_x+(radius-25)*math.cos(i*30*np.pi/180.0)
  y = center_y+(radius-25)*math.sin(i*30*np.pi/180.0)
  # 这里用到了前面的pt1
  cv.line(img, pt1[i*5], (int(x), int(y)), (0, 0, 0), thickness=5)


# 到这里基本的表盘图就已经画出来了

角度换算

这是一个关键步骤。时钟起始坐标位于正常二维坐标系的90°方向,且时钟与图像均按顺时针计算角度,因此需要进行统一换算:

由于角度具有对称性,顺逆时针不影响结果,此处列出平面坐标系仅为辅助理解。时钟坐标与图像坐标的对应关系为:时钟0点的0°对应图像270°,时钟15分的90°对应图像360°,时钟30分的180°对应图像450°(即360°+90°)。两者转换公式为:计算角度 = 时钟角度+270°;若计算角度>360°,则计算角度 = 计算角度-360°。

同步时间

在Python中获取当前时间和添加日期文字较为简单,具体实现请参考代码,此处不再赘述。


while(1):
  # 不断拷贝表盘图,才能更新绘制,不然会重叠在一起
  temp = np.copy(img)

  # 5. 获取系统时间,画出动态的时-分-秒三条刻线
  now_time = datetime.datetime.now()
  hour, minute, second = now_time.hour, now_time.minute, now_time.second

  # 画秒刻线
  # 参见博客,OpenCV中的角度是顺时针计算的,所以需要转换下
  sec_angle = second*6+270 if second <= 15 else (second-15)*6
  sec_x = center_x+(radius-margin)*math.cos(sec_angle*np.pi/180.0)
  sec_y = center_y+(radius-margin)*math.sin(sec_angle*np.pi/180.0)
  cv.line(temp, center, (int(sec_x), int(sec_y)), (255, 0, 0), 2)

  # 画分刻线
  min_angle = minute*6+270 if minute <= 15 else (minute-15)*6
  min_x = center_x+(radius-35)*math.cos(min_angle*np.pi/180.0)
  min_y = center_y+(radius-35)*math.sin(min_angle*np.pi/180.0)
  cv.line(temp, center, (int(min_x), int(min_y)), (0, 255, 0), 8)

  # 画时刻线
  hour_angle = hour*30+270 if hour <= 3 else (hour-3)*30
  hour_x = center_x+(radius-75)*math.cos(hour_angle*np.pi/180.0)
  hour_y = center_y+(radius-75)*math.sin(hour_angle*np.pi/180.0)
  cv.line(temp, center, (int(hour_x), int(hour_y)), (0, 0, 255), 20)

  # 6. 添加当前日期文字
  font = cv.FONT_HERSHEY_SIMPLEX
  time_str = now_time.strftime("%d/%m/%Y")
  cv.putText(img, time_str, (135, 275), font, 1, (0, 0, 0), 2)

  cv.imshow('clocking', temp)
  if cv.waitKey(1) == 27: # 按下ESC键退出
    break

以上即为Python基于OpenCV实现图像时钟的详细内容,更多关于Python OpenCV实现图像时钟的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。