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

Python在图片上画矩形:从简单边框到复杂标注的全攻略

在上一篇博客中,我们学会了如何在图片上画线。而在实际的图像处理项目中,画矩形(Rectangle)的使用频率甚至比画线还要高。

无论是目标检测中的边界框(Bounding Box)OCR识别中的文字区域高亮,还是隐私保护中的马赛克遮挡,本质上都是在画矩形。

今天,我们将继续使用OpenCVPillow这两个利器,深入讲解如何在 Python 中优雅地画矩形。


一、 为什么矩形如此重要?

  • 目标检测:YOLO、Faster R-CNN 等模型输出的结果通常是矩形框坐标(x, y, w, h)
  • ROI 提取:通过矩形框选感兴趣区域(Region of Interest),进行裁剪或单独处理。
  • 数据脱敏:用矩形色块覆盖身份证号、车牌、人脸。

二、 核心参数解析

在开始写代码前,先记住画矩形的几个核心要素:

  1. 左上角坐标(x1, y1)
  2. 右下角坐标(x2, y2)
    • 注意:有些库也支持传入[x1, y1, x2, y2]列表。
  3. 颜色:RGB 或 BGR 元组。
  4. 线宽/填充:是只画边框,还是填充整个矩形?

三、 OpenCV 实现:cv2.rectangle()

OpenCV 是计算机视觉的首选,它的rectangle函数非常高效,支持 numpy 数组操作。

1. 基础用法:画一个红色边框

importcv2importnumpyasnp# 创建一张黑色背景图img=np.zeros((500,500,3),dtype=np.uint8)# 定义左上角和右下角坐标pt1=(50,50)# (x, y)pt2=(400,300)# (x, y)# 定义颜色 (OpenCV 是 BGR,所以 (0, 0, 255) 是红色)color=(0,0,255)# 定义线宽 (如果是 -1,表示填充)thickness=3# 画矩形cv2.rectangle(img,pt1,pt2,color,thickness)cv2.imshow("OpenCV Rectangle",img)cv2.waitKey(0)cv2.destroyAllWindows()

2. 进阶技巧

A. 画实心矩形(马赛克遮挡神器)

只需将thickness设置为-1即可填充矩形。这常用于遮挡敏感信息。

# 画一个绿色的实心矩形cv2.rectangle(img,(50,350),(450,450),(0,255,0),-1)
B. 画圆角矩形(OpenCV 没有直接函数,需要自己实现)

OpenCV 原生不支持圆角矩形,但我们可以通过画线和圆组合,或者用循环画短线来模拟。这里教大家一个简单的“伪圆角”方法:

# 简单的圆角矩形函数defdraw_rounded_rectangle(img,pt1,pt2,color,radius,thickness):x1,y1=pt1 x2,y2=pt2# 画四条边cv2.line(img,(x1+radius,y1),(x2-radius,y1),color,thickness)cv2.line(img,(x1+radius,y2),(x2-radius,y2),color,thickness)cv2.line(img,(x1,y1+radius),(x1,y2-radius),color,thickness)cv2.line(img,(x2,y1+radius),(x2,y2-radius),color,thickness)# 画四个角cv2.circle(img,(x1+radius,y1+radius),radius,color,thickness)cv2.circle(img,(x2-radius,y1+radius),radius,color,thickness)cv2.circle(img,(x1+radius,y2-radius),radius,color,thickness)cv2.circle(img,(x2-radius,y2-radius),radius,color,thickness)# 使用draw_rounded_rectangle(img,(50,50),(250,200),(255,255,0),20,2)

四、 Pillow 实现:ImageDraw.rectangle()

Pillow 的 API 在处理坐标时更加灵活,支持直接传入列表,且颜色是直观的 RGB。

1. 基础用法

fromPILimportImage,ImageDraw# 创建白色背景图img=Image.new('RGB',(500,500),color='white')draw=ImageDraw.Draw(img)# 坐标可以是 [左上角x, 左上角y, 右下角x, 右下角y]box=[50,50,400,300]# 画蓝色边框,宽度为 3draw.rectangle(box,outline='blue',width=3)# 画一个红色实心矩形draw.rectangle([50,350,450,450],fill='red')img.show()

2. Pillow 的独特优势:支持多边形裁剪

Pillow 的rectangle其实可以接受任意多边形坐标(只要是矩形框选逻辑),或者配合ImageDraw.polygon使用更自由。


五、 实战案例:三个高价值场景

场景 1:给检测到的物体打标签(带文字的矩形)

在目标检测中,我们通常在矩形上方贴一个带背景色的文字标签。

importcv2 img=cv2.imread("test.jpg")# 假设有一张原图x,y,w,h=100,100,200,300# 模拟检测框# 1. 画矩形框cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)# 2. 画文字背景(实心小矩形)label="Person"(text_width,text_height),_=cv2.getTextSize(label,cv2.FONT_HERSHEY_SIMPLEX,0.6,2)cv2.rectangle(img,(x,y-25),(x+text_width,y),(0,255,0),-1)# 填充# 3. 写文字cv2.putText(img,label,(x,y-5),cv2.FONT_HERSHEY_SIMPLEX,0.6,(255,255,255),2)cv2.imshow("Labeled",img)cv2.waitKey(0)

场景 2:高级马赛克(网格状矩形)

简单的实心矩形太生硬,真正的马赛克是由很多小矩形组成的。

defapply_mosaic(img,x,y,w,h,block_size=10):""" 对指定区域 (x, y, w, h) 进行马赛克处理 """roi=img[y:y+h,x:x+w]# 缩小再放大,模拟马赛克roi=cv2.resize(roi,(w//block_size,h//block_size),interpolation=cv2.INTER_LINEAR)roi=cv2.resize(roi,(w,h),interpolation=cv2.INTER_NEAREST)img[y:y+h,x:x+w]=roireturnimg# 使用img=cv2.imread("face.jpg")img=apply_mosaic(img,50,50,200,200)cv2.imshow("Mosaic",img)cv2.waitKey(0)

注:虽然这用了 resize,但原理上是把像素块变成了“大矩形”。

场景 3:半透明遮罩(Highlight)

有时候我们需要高亮某个区域,但又不想完全遮住原图。

importcv2importnumpyasnp img=cv2.imread("test.jpg")overlay=img.copy()# 定义区域x,y,w,h=100,100,300,300# 在覆盖层上画一个半透明矩形# 先画一个实心矩形cv2.rectangle(overlay,(x,y),(x+w,y+h),(255,0,0),-1)# 混合原图和覆盖层 (alpha=0.3 表示覆盖层透明度)cv2.addWeighted(overlay,0.3,img,0.7,0,img)cv2.imshow("Transparent Overlay",img)cv2.waitKey(0)

六、 OpenCV vs Pillow:画矩形该选谁?

特性OpenCV (cv2.rectangle)Pillow (ImageDraw.rectangle)
坐标系左上角(0,0),向右下增长左上角(0,0),向右下增长
参数(img, pt1, pt2, color, thickness)(xy, outline, fill, width)
填充thickness = -1fill = 'color'
性能极快(底层C++,支持Numpy)中等 (纯Python实现部分)
颜色BGR(易错点)RGB(直观)
推荐场景视频处理、实时检测、算法开发批量图片处理、Web后端生成图

七、 总结

画矩形看似简单,但在实际应用中往往需要结合坐标计算颜色空间转换图层混合

  • 如果你在做YOLO/SSD 目标检测OpenCV 项目,请熟练掌握cv2.rectangle,特别是利用-1做遮挡,利用addWeighted做半透明高亮。
  • 如果你在做Pillow 脚本处理,记得它的参数更人性化,支持直接传列表。
http://www.jsqmd.com/news/662887/

相关文章:

  • 用PyTorch实现5种自编码器:从基础到变分(附完整代码)
  • 5G NR物理层探秘:PBCH信道与MIB消息的编码、映射与波束赋形
  • 提交的后悔药:amend、reset、revert命令的适用场景与风险
  • LaTeX表格浮动控制:从自动上移到精准定位的实用指南
  • BiliBiliCCSubtitle终极指南:快速下载B站CC字幕的完整教程
  • YOLOv8自定义数据集训练全流程:从VisDrone.yaml配置到模型验证
  • 从‘Hello World’到封装自己的数学库:一个gcc动态库.so的完整项目实战
  • C#VisionMaster算子深度封装实战(非方案版)
  • 提交的时空管理:stash命令暂存工作现场与分支切换策略
  • 绿色极简:一款712KB的快捷回复工具深度解析
  • 技术选型指南:如何评估ABAP Excel生成工具的企业级应用价值
  • STC89C52单片机+ADC0832+DHT11:手把手教你做一个能自动浇花的毕设项目(附完整代码)
  • 从零到量产:AMR机器人底盘选型与集成避坑指南(附主流供应商清单)
  • Python数据可视化之散点图(实战篇---从入门到精通)
  • 从零搭建Adams-Matlab机器人联合仿真环境:一份详尽的配置指南
  • 别再手动传文件了!手把手教你用Alfresco搭建企业文档共享中心(含Word在线编辑避坑指南)
  • 从PC到移动端:高通安卓UEFI的架构演进与核心设计
  • ORAN专题系列-23:O-RU全球生态格局与新兴势力深度解析
  • 嵌入式音频延迟优化:如何为你的ARM Linux设备(如树莓派)调优ALSA Buffer参数
  • 全志A133安卓10设备GPS功能移植实战:从HAL层配置到天线选型避坑全记录
  • 保姆级教程:用Python脚本实现URSim机器人TCP通讯控制(附完整代码)
  • RDKit终极指南:3个核心功能解析与5大实战应用场景
  • Xilinx Video IP(二)AXI4-Stream视频数据流优化与FIFO深度设计
  • 客服效率革命:如何用咕咕文本实现秒级响应
  • 【OpenClaw从入门到精通】第66篇:Skill开发进阶——从零打造一个跨境选品Skill(附完整代码)(2026实测版)
  • Python在图片上画线:从基础到进阶的实用指南
  • 学Simulink——基于Simulink的感应电机间接转子磁场定向控制​
  • SAP运维实战 - 番号范围缺失引发的NR751错误:从RF_BELEG R100到FBN1的修复之旅
  • 从抛硬币到投资组合:独立随机变量‘可加性’在现实世界中的3个妙用
  • 从哈勃到韦伯:J2000坐标系在太空望远镜观测中的关键作用与实战案例