使用Python在圖片上畫線的兩種主流方法
在日常的編程工作中,我們經(jīng)常需要對圖像進行處理。無論是給圖片加水印、標(biāo)注目標(biāo)檢測的邊框,還是簡單的圖像編輯,“在圖片上畫線”都是最基礎(chǔ)也是最常用的操作之一。
今天,我們就來詳細(xì)聊聊如何使用 Python 在圖片上畫線。我們將主要使用兩個強大的庫:OpenCV 和 Pillow (PIL)。
一、 準(zhǔn)備工作:安裝依賴庫
在開始之前,請確保你已經(jīng)安裝了必要的庫。打開終端(Terminal 或 CMD),運行以下命令:
# 安裝 OpenCV (推薦用于計算機視覺任務(wù)) pip install opencv-python numpy # 安裝 Pillow (推薦用于簡單的圖像處理) pip install Pillow
二、 核心概念:坐標(biāo)系與顏色
在畫線之前,有兩個概念必須搞懂,否則你畫出的線可能會“消失”或者顏色不對。
- 坐標(biāo)系:
- 在計算機視覺中,圖像的左上角是原點
(0, 0)。 - X 軸向右增長,Y 軸向下增長。
- 坐標(biāo)格式通常是
(x, y)或者(列, 行)。
- 在計算機視覺中,圖像的左上角是原點
- 顏色通道:
- OpenCV 使用的是 BGR 格式(藍、綠、紅),而不是常見的 RGB。
- Pillow 使用的是 RGB 格式。
- 顏色值通常是 0-255 的整數(shù)元組,例如紅色在 OpenCV 中是
(0, 0, 255),在 Pillow 中是(255, 0, 0)。
三、 方法一:使用 OpenCV (cv2) —— 專業(yè)且強大
OpenCV 是計算機視覺領(lǐng)域的行業(yè)標(biāo)準(zhǔn),功能極其豐富。
1. 基礎(chǔ)畫線:cv2.line()
這是最直接的方法。
import cv2
import numpy as np
# 1. 創(chuàng)建一張黑色的空白圖片 (高500, 寬500, 3通道)
# 注意:OpenCV 的 shape 順序是 (高度, 寬度, 通道數(shù))
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 甚至提供了現(xiàn)成的箭頭函數(shù):
# 在上面的代碼基礎(chǔ)上替換 cv2.line 為: cv2.arrowedLine(image, (50, 100), (450, 100), (0, 255, 0), 5, tipLength=0.1)
B. 畫虛線/抗鋸齒線
cv2.line 默認(rèn)可能會有鋸齒。如果要更平滑的線(抗鋸齒),可以使用 cv2.LINE_AA 標(biāo)志(但在較新版本中,line_type 參數(shù)已被整合,通常高分辨率下直接畫即可,或者使用更復(fù)雜的繪制方法)。
如果你想畫虛線,OpenCV 沒有直接函數(shù),需要自己寫個小邏輯:
def draw_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_len
if steps == 0: steps = 1
for i in range(0, steps, 2): # 每隔一段畫一段
t1 = i / steps
t2 = (i + 1) / steps if (i + 1) < steps else 1.0
p1 = (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,更容易上手。
from PIL import Image, ImageDraw
# 1. 創(chuàng)建一張白色背景的圖片
img = Image.new('RGB', (500, 500), color='white')
# 2. 創(chuàng)建一個可以在上面繪制的對象
draw = ImageDraw.Draw(img)
# 3. 定義坐標(biāo) [(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)
# 也可以連續(xù)畫多條線段
draw.line([(50, 100), (200, 100), (200, 200), (350, 200)], fill='blue', width=3, joint='curve')
# 6. 顯示圖片 (會調(diào)用系統(tǒng)默認(rèn)圖片查看器)
img.show()
# 7. 保存
img.save("pillow_line.jpg")
Pillow 的優(yōu)勢:
- 坐標(biāo)可以直接用列表
[(x1,y1), (x2,y2)],也支持連續(xù)點。 - 顏色可以直接用英文單詞
'red','blue'。 - 支持
joint參數(shù)讓折線拐角處變圓滑。
五、 實戰(zhàn)案例:給圖片打馬賽克(畫粗線覆蓋)
有時候我們需要遮擋圖片中的敏感信息(如車牌、人臉),最簡單的方法就是在上面畫粗線或者矩形覆蓋。
需求:在圖片上畫一條黑色的粗橫線遮擋文字。
import cv2
# 讀取圖片
img = cv2.imread("test_image.jpg") # 替換成你的圖片路徑
# 定義遮擋區(qū)域的Y坐標(biāo)范圍
y_top = 100
y_bottom = 150
# 在這個區(qū)域內(nèi)畫黑色的粗線(實際上畫矩形更合適,但畫線也能模擬)
# 這里我們用循環(huán)畫多條線模擬粗線帶,或者直接用 rectangle
start_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)
六、 總結(jié)與建議
| 特性 | OpenCV (cv2) | Pillow (PIL) |
|---|---|---|
| 主要用途 | 計算機視覺、視頻分析、復(fù)雜圖像算法 | 基礎(chǔ)圖像處理、Web后端圖片生成、格式轉(zhuǎn)換 |
| 畫線函數(shù) | cv2.line() | ImageDraw.line() |
| 顏色格式 | BGR (容易踩坑) | RGB (符合直覺) |
| 坐標(biāo)系 | (x, y) / (列, 行) | (x, y) |
| 性能 | 極高 (C++底層) | 中等 (Python底層) |
| 易用性 | 稍復(fù)雜,參數(shù)多 | 非常簡單,API友好 |
我的建議:
- 如果你在做目標(biāo)檢測、人臉識別、視頻流處理,請無腦選擇 OpenCV。
- 如果你只是想給照片加個水印、生成驗證碼、簡單的裁剪縮放,Pillow 會讓你寫得更開心。
以上就是使用Python在圖片上畫線的兩種主流方法的詳細(xì)內(nèi)容,更多關(guān)于Python在圖片上畫線的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python中數(shù)據(jù)清洗與處理的常用方法小結(jié)
數(shù)據(jù)清洗與處理是數(shù)據(jù)分析的重要步驟,確保數(shù)據(jù)的準(zhǔn)確性和一致性,這篇文章為大家整理了Python中一些常用的數(shù)據(jù)清洗與處理方法,需要的可以參考下2025-02-02
python將txt等文件中的數(shù)據(jù)讀為numpy數(shù)組的方法
今天小編就為大家分享一篇python將txt等文件中的數(shù)據(jù)讀為numpy數(shù)組的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12
Python基于多線程實現(xiàn)抓取數(shù)據(jù)存入數(shù)據(jù)庫的方法
這篇文章主要介紹了Python基于多線程實現(xiàn)抓取數(shù)據(jù)存入數(shù)據(jù)庫的方法,結(jié)合實例形式分析了Python使用數(shù)據(jù)庫類與多線程類進行數(shù)據(jù)抓取與寫入數(shù)據(jù)庫操作的具體使用技巧,需要的朋友可以參考下2018-06-06
Python 將代碼轉(zhuǎn)換為可執(zhí)行文件脫離python環(huán)境運行(步驟詳解)
這篇文章主要介紹了Python 將代碼轉(zhuǎn)換為可執(zhí)行文件脫離python環(huán)境運行(步驟詳解),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01

