Python在图片上画圆形:从入门到实战

在计算机视觉和图像处理领域,我们经常需要在图片上标记特定的区域,比如在人脸识别框出人脸、在目标检测中标出物体位置,或者仅仅是为了给图片加一个水印 Logo。其中,画圆是最基础也是最常用的操作之一。

今天,我们就来聊聊如何使用 Python 在图片上画出漂亮的圆形。我们将主要使用两个最流行的库:OpenCVPillow (PIL)


一、 准备工作:安装依赖库

在开始之前,请确保你的环境中安装了必要的库。推荐使用 pip 安装:

bash 复制代码
# 安装 OpenCV (功能最强大,推荐)
pip install opencv-python

# 安装 Pillow (轻量级,也很常用)
pip install Pillow

# 安装 NumPy (OpenCV 依赖它)
pip install numpy

同时,准备一张测试图片,假设我们将其命名为 test_image.jpg,并放在代码同级目录下。


二、 方法一:使用 OpenCV (cv2) ------ 行业标准

OpenCV 是计算机视觉领域的瑞士军刀。它的 cv2.circle() 函数非常高效,支持抗锯齿、填充、不同颜色等多种特性。

1. 基础代码示例

python 复制代码
import cv2
import numpy as np

# 1. 读取图片
image = cv2.imread('test_image.jpg')

# 检查图片是否成功读取
if image is None:
    print("错误:无法读取图片,请检查路径")
    exit()

# 2. 定义圆的参数
center_coordinates = (300, 300)  # 圆心坐标 (x, y)
radius = 100                     # 半径
color = (0, 255, 0)              # 颜色 (BGR 格式:蓝, 绿, 红),这里是绿色
thickness = 5                    # 线条粗细 (-1 表示填充实心圆)

# 3. 画圆
# cv2.circle(图像, 圆心, 半径, 颜色, 粗细)
cv2.circle(image, center_coordinates, radius, color, thickness)

# 4. 显示图片
cv2.imshow('Image with Circle', image)

# 5. 保存图片
cv2.imwrite('result_opencv.jpg', image)

# 等待按键并关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

2. 核心参数详解

  • 坐标系统 :OpenCV 使用的是 左上角为原点 (0,0) 的坐标系,向右是 X 轴正方向,向下是 Y 轴正方向。
  • 颜色 (BGR) :注意!OpenCV 默认使用 BGR 顺序,而不是常见的 RGB。
    • (255, 0, 0) 是蓝色
    • (0, 255, 0) 是绿色
    • (0, 0, 255) 是红色
  • thickness (粗细)
    • 如果是正整数(如 5),表示边框的像素宽度。
    • 如果是 -1,表示画一个实心圆

3. 进阶:画半透明圆

OpenCV 本身不直接支持透明度通道的混合,但我们可以通过 addWeighted 函数模拟半透明效果:

python 复制代码
# 创建一个覆盖层
overlay = image.copy()
cv2.circle(overlay, (300, 300), 100, (0, 255, 0), -1)

# 混合原图和覆盖层 (原图权重0.7, 覆盖层权重0.3)
alpha = 0.3
cv2.addWeighted(overlay, alpha, image, 1 - alpha, 0, image)

三、 方法二:使用 Pillow (PIL) ------ 轻量简洁

如果你只是做简单的图片编辑,不需要复杂的计算机视觉算法,Pillow 是更轻量、更符合 Python 直觉的选择。

1. 基础代码示例

Pillow 画圆的逻辑稍微不同,它是通过 ellipse(椭圆)函数来画圆的,或者使用 ImageDraw 的圆弧方法。最简单的是用椭圆(当长宽相等时即为圆)。

python 复制代码
from PIL import Image, ImageDraw

# 1. 打开图片
image = Image.open('test_image.jpg')
draw = ImageDraw.Draw(image)

# 2. 定义圆的参数
# Pillow 使用 [左上角x, 左上角y, 右下角x, 右下角y] 的坐标格式
x, y = 300, 300
radius = 100
bounding_box = [x - radius, y - radius, x + radius, y + radius]

# 3. 画圆
# outline 是边框颜色, width 是边框宽度
# 如果只想画边框,不要 fill 或者设置 fill=None
draw.ellipse(bounding_box, outline=(255, 0, 0), width=5) 

# 如果想画实心圆,加上 fill 参数
# draw.ellipse(bounding_box, fill=(255, 0, 0), outline=None)

# 4. 显示图片 (会调用系统默认图片查看器)
image.show()

# 5. 保存图片
image.save('result_pillow.jpg')

2. Pillow vs OpenCV 对比

特性 OpenCV (cv2) Pillow (PIL)
颜色格式 BGR (容易踩坑) RGB (符合直觉)
坐标定义 圆心点 + 半径 左上角 + 右下角 (外接矩形)
性能 极高 (C++底层) 中等 (Python底层)
依赖 较重 (NumPy等) 轻量
适用场景 视频分析、实时处理、复杂算法 简单的图片编辑、Web后端生成图片

四、 实战案例:在人脸上画"眼镜"圆

假设我们要在图片中心画一个红色的实心圆,模拟一个简单的标记。

使用 OpenCV 实现:

python 复制代码
import cv2

# 读取图片
img = cv2.imread('test_image.jpg')
h, w, _ = img.shape  # 获取图片高宽

# 计算中心点
center = (w // 2, h // 2)

# 画一个红色的实心圆 (BGR: 0, 0, 255)
cv2.circle(img, center, 50, (0, 0, 255), -1)

# 添加文字说明
cv2.putText(img, "Center Point", (center[0] - 50, center[1] - 60), 
            cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)

cv2.imshow('Center Marker', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

五、 常见问题 (FAQ)

Q1: 为什么我画的圆颜色不对?比如想画红色却变成了蓝色?
A: 这是 OpenCV 最经典的坑。OpenCV 使用 BGR 顺序。如果你习惯了 RGB,请记得转换:(R, G, B) -> (B, G, R)。或者在显示前转换色彩空间:cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

Q2: 图片显示一闪而过怎么办?
A : 在 cv2.imshow 之后,一定要加 cv2.waitKey(0),这行代码的意思是"等待任意按键输入",如果没有它,窗口会因为程序执行完毕而直接关闭。

Q3: 如何画一个只有轮廓没有填充的圆?
A:

  • OpenCV: thickness 设为正数(如 1, 2, 5)。
  • Pillow: ellipse 函数中设置 fill=None 或不写 fill,只写 outlinewidth

六、 总结

Python 在图片上画圆其实非常简单:

  • 如果你追求性能专业功能 ,请首选 OpenCVcv2.circle()
  • 如果你只是做简单的脚本Web图片生成PillowImageDraw.ellipse() 更简单易用。

掌握了画圆,你就掌握了图像标注的基础。下一步,你可以尝试画矩形(cv2.rectangle)、多边形(cv2.polylines),甚至是贝塞尔曲线。

赶紧打开编辑器,给你的图片加上一个酷炫的圆吧!


如果你觉得这篇文章有帮助,欢迎点赞、收藏并分享给你的开发者朋友!

相关推荐
小江的记录本2 小时前
【系统设计】《2026高频经典系统设计题》(秒杀系统、短链接系统、订单系统、支付系统、IM系统、RAG系统设计)(完整版)
java·后端·python·安全·设计模式·架构·系统架构
m0_377618232 小时前
HTML怎么显示速率限制重置时间_HTML X-RateLimit-Reset解析【说明】
jvm·数据库·python
u0109147602 小时前
C#怎么实现OAuth2.0授权_C#如何对接第三方快捷登录【核心】
jvm·数据库·python
桌面运维家2 小时前
IDV云桌面vDisk机房部署方案模板特性解析
java·开发语言·devops
2301_777599372 小时前
如何显著提升 Google Sheets 数据库批量更新脚本的执行效率
jvm·数据库·python
飞翔的SA2 小时前
从6.75%到100%!大模型Function Calling终极方案:Harness工程如何驯服
开发语言·ai·llm·harness
2201_761040592 小时前
bootstrap怎么给div添加自定义的边框样式
jvm·数据库·python
Java后端的Ai之路2 小时前
当大模型开始“水土不服“:从通才到专才的进化论——Fine-tuning 企业级实战全攻略
人工智能·python·langchain·rag·lcel
weixin_568996062 小时前
Golang怎么用K8s Job执行一次性任务_Golang如何用Job资源运行批处理和迁移任务【操作】
jvm·数据库·python