当前位置: 首页 > news >正文

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

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

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


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

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

# 安装 OpenCV (功能最强大,推荐)pipinstallopencv-python# 安装 Pillow (轻量级,也很常用)pipinstallPillow# 安装 NumPy (OpenCV 依赖它)pipinstallnumpy

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


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

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

1. 基础代码示例

importcv2importnumpyasnp# 1. 读取图片image=cv2.imread('test_image.jpg')# 检查图片是否成功读取ifimageisNone: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函数模拟半透明效果:

# 创建一个覆盖层overlay=image.copy()cv2.circle(overlay,(300,300),100,(0,255,0),-1)# 混合原图和覆盖层 (原图权重0.7, 覆盖层权重0.3)alpha=0.3cv2.addWeighted(overlay,alpha,image,1-alpha,0,image)

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

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

1. 基础代码示例

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

fromPILimportImage,ImageDraw# 1. 打开图片image=Image.open('test_image.jpg')draw=ImageDraw.Draw(image)# 2. 定义圆的参数# Pillow 使用 [左上角x, 左上角y, 右下角x, 右下角y] 的坐标格式x,y=300,300radius=100bounding_box=[x-radius,y-radius,x+radius,y+radius]# 3. 画圆# outline 是边框颜色, width 是边框宽度# 如果只想画边框,不要 fill 或者设置 fill=Nonedraw.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 实现:

importcv2# 读取图片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),甚至是贝塞尔曲线。

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


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

http://www.jsqmd.com/news/668184/

相关文章:

  • 3步恢复Windows 11 LTSC微软商店:完整应用生态一键安装指南
  • 【Linux从入门到精通】第6篇:管道符、重定向与通配符——命令行效率的核心秘诀
  • Windows服务器运维:如何用mstsc命令和.rdp配置文件打造你的专属远程桌面管理库
  • 【传播模型】CoVeni计算并可视化了病毒附Matlab代码
  • 别光会binwalk了!CTF MISC实战中这5个冷门但好用的文件分析工具,帮你快速定位flag
  • 三步搞定Windows ADB驱动安装:告别繁琐配置,专注Android开发
  • 阿里云盘的FatalError
  • Win11Debloat:三步彻底清理Windows系统,让电脑重获新生
  • 【数字信号调制】自适应调制解调通信系统误码率仿真【含Matlab源码 15364期】
  • LangGraph 并行执行优化:如何提升多智能体任务处理效率?
  • 告别Tomcat:Spring Boot应用改造为纯War包,适配宝兰德等商用中间件全指南
  • Python在图片上画多边形:从简单轮廓到复杂区域标注
  • **发散创新:用Python实现因果推理在推荐系统中的落地应用**在当今数据
  • 【AI面试八股文 Vol.1.1 | 专题4:Conditional Edge】Conditional Edge:动态路由分支逻辑实现
  • SolidWorks参数化设计避坑指南:为什么你的VBA宏跑一次就报错?
  • 家庭网络总断网?可能是你家的路由器接错了!用环路检测功能快速排查
  • Unity Magica Cloth:从入门到精通,打造次世代角色动态服饰
  • 别再只用MD5了!聊聊PBKDF2如何用‘盐’和‘慢炖’保护你的用户密码
  • OpenClaw怎么搭建?2026年4月云端大模型Coding Plan配置指南
  • 如何快速掌握CREST:药物设计中分子构象采样的完整指南
  • NVIDIA Profile Inspector 终极指南:解锁隐藏设置,轻松优化游戏性能
  • 2026年降AI后重新检测还是偏高怎么处理:多轮降AI完整攻略
  • Orwell Dev-C++ 和 Embarcadero Dev-C++ 哪个更好
  • (build/soong/scripts/manifest_check.py --enforce-uses-libraries --enforce-uses-libraries-status
  • 从E·M·福斯特的《英国人性格的笔记》看技术文档写作:如何避免“未发育的心”与“自满的陷阱”
  • 【AI面试临阵磨枪】什么是 Tokenization?子词分词(Subword)的优缺点?
  • 保姆级教程:在CentOS 7上为Zabbix 6.0配置LAMP环境(Apache+MySQL 8.0+PHP 7.4)
  • 别只发GET请求了!ESP32的HTTPClient库POST数据到服务器,保姆级配置流程(含模拟测试)
  • Android Camera HAL层开发指南:深入理解camera3_profiles_rkxxxx.xml的metadata解析机制
  • 在setting菜单里显示的有些字符 不正常,