Python在图片上画线:从基础到进阶的实用指南
在日常的编程工作中,我们经常需要对图像进行处理。无论是给图片加水印、标注目标检测的边框,还是简单的图像编辑,“在图片上画线”都是最基础也是最常用的操作之一。
今天,我们就来详细聊聊如何使用 Python 在图片上画线。我们将主要使用两个强大的库:OpenCV和Pillow (PIL)。
一、 准备工作:安装依赖库
在开始之前,请确保你已经安装了必要的库。打开终端(Terminal 或 CMD),运行以下命令:
# 安装 OpenCV (推荐用于计算机视觉任务)pipinstallopencv-python numpy# 安装 Pillow (推荐用于简单的图像处理)pipinstallPillow二、 核心概念:坐标系与颜色
在画线之前,有两个概念必须搞懂,否则你画出的线可能会“消失”或者颜色不对。
- 坐标系:
- 在计算机视觉中,图像的左上角是原点
(0, 0)。 - X 轴向右增长,Y 轴向下增长。
- 坐标格式通常是
(x, y)或者(列, 行)。
- 在计算机视觉中,图像的左上角是原点
- 颜色通道:
- OpenCV使用的是BGR格式(蓝、绿、红),而不是常见的 RGB。
- Pillow使用的是RGB格式。
- 颜色值通常是 0-255 的整数元组,例如红色在 OpenCV 中是
(0, 0, 255),在 Pillow 中是(255, 0, 0)。
三、 方法一:使用 OpenCV (cv2) —— 专业且强大
OpenCV 是计算机视觉领域的行业标准,功能极其丰富。
1. 基础画线:cv2.line()
这是最直接的方法。
importcv2importnumpyasnp# 1. 创建一张黑色的空白图片 (高500, 宽500, 3通道)# 注意:OpenCV 的 shape 顺序是 (高度, 宽度, 通道数)image=np.zeros((500,500,3),dtype=np.uint8)# 2. 定义起点和终点start_point=(50,50)# (x, y)end_point=(450,450)# 3. 定义颜色 (BGR格式:蓝色)color=(255,0,0)# 4. 定义线宽thickness=5# 5. 画线cv2.line(image,start_point,end_point,color,thickness)# 6. 显示图片cv2.imshow("OpenCV Line",image)cv2.waitKey(0)# 等待按键cv2.destroyAllWindows()# 7. 保存图片cv2.imwrite("opencv_line.jpg",image)2. 进阶玩法
A. 画带箭头的线
OpenCV 甚至提供了现成的箭头函数:
# 在上面的代码基础上替换 cv2.line 为:cv2.arrowedLine(image,(50,100),(450,100),(0,255,0),5,tipLength=0.1)B. 画虚线/抗锯齿线
cv2.line默认可能会有锯齿。如果要更平滑的线(抗锯齿),可以使用cv2.LINE_AA标志(但在较新版本中,line_type 参数已被整合,通常高分辨率下直接画即可,或者使用更复杂的绘制方法)。
如果你想画虚线,OpenCV 没有直接函数,需要自己写个小逻辑:
defdraw_dashed_line(img,start,end,color,thickness=1,dash_len=10):x1,y1=start x2,y2=end dx,dy=x2-x1,y2-y1 steps=max(abs(dx),abs(dy))//dash_lenifsteps==0:steps=1foriinrange(0,steps,2):# 每隔一段画一段t1=i/steps t2=(i+1)/stepsif(i+1)<stepselse1.0p1=(int(x1+t1*dx),int(y1+t1*dy))p2=(int(x1+t2*dx),int(y1+t2*dy))cv2.line(img,p1,p2,color,thickness)# 使用draw_dashed_line(image,(50,200),(450,200),(0,255,255),3)C. 画半透明线
OpenCV 画半透明线稍微麻烦一点,需要使用cv2.addWeighted进行图像混合:
overlay=image.copy()cv2.line(overlay,(50,300),(450,300),(0,0,255),10)# 红色粗线# 混合原图和覆盖层cv2.addWeighted(overlay,0.5,image,0.5,0,image)四、 方法二:使用 Pillow (PIL) —— 轻量且直观
如果你只是做简单的图片编辑(如加水印、画装饰线),Pillow 的 API 更加 Pythonic,更容易上手。
fromPILimportImage,ImageDraw# 1. 创建一张白色背景的图片img=Image.new('RGB',(500,500),color='white')# 2. 创建一个可以在上面绘制的对象draw=ImageDraw.Draw(img)# 3. 定义坐标 [(x1, y1), (x2, y2)]xy=[50,50,450,450]# 4. 定义颜色 (RGB格式:红色) 和线宽fill_color=(255,0,0)width=5# 5. 画线draw.line(xy,fill=fill_color,width=width)# 也可以连续画多条线段draw.line([(50,100),(200,100),(200,200),(350,200)],fill='blue',width=3,joint='curve')# 6. 显示图片 (会调用系统默认图片查看器)img.show()# 7. 保存img.save("pillow_line.jpg")Pillow 的优势:
- 坐标可以直接用列表
[(x1,y1), (x2,y2)],也支持连续点。 - 颜色可以直接用英文单词
'red','blue'。 - 支持
joint参数让折线拐角处变圆滑。
五、 实战案例:给图片打马赛克(画粗线覆盖)
有时候我们需要遮挡图片中的敏感信息(如车牌、人脸),最简单的方法就是在上面画粗线或者矩形覆盖。
需求:在图片上画一条黑色的粗横线遮挡文字。
importcv2# 读取图片img=cv2.imread("test_image.jpg")# 替换成你的图片路径# 定义遮挡区域的Y坐标范围y_top=100y_bottom=150# 在这个区域内画黑色的粗线(实际上画矩形更合适,但画线也能模拟)# 这里我们用循环画多条线模拟粗线带,或者直接用 rectanglestart_point=(0,y_top)end_point=(img.shape[1],y_bottom)# img.shape[1] 是宽度# 画一个填充的矩形来遮挡cv2.rectangle(img,start_point,end_point,(0,0,0),-1)# -1 表示填充cv2.imshow("Censored",img)cv2.waitKey(0)六、 总结与建议
| 特性 | OpenCV (cv2) | Pillow (PIL) |
|---|---|---|
| 主要用途 | 计算机视觉、视频分析、复杂图像算法 | 基础图像处理、Web后端图片生成、格式转换 |
| 画线函数 | cv2.line() | ImageDraw.line() |
| 颜色格式 | BGR(容易踩坑) | RGB(符合直觉) |
| 坐标系 | (x, y) / (列, 行) | (x, y) |
| 性能 | 极高 (C++底层) | 中等 (Python底层) |
| 易用性 | 稍复杂,参数多 | 非常简单,API友好 |
我的建议:
- 如果你在做目标检测、人脸识别、视频流处理,请无脑选择OpenCV。
- 如果你只是想给照片加个水印、生成验证码、简单的裁剪缩放,Pillow会让你写得更开心。
