使用Python在圖片上畫矩形全攻略
在實際的圖像處理項目中,畫矩形(Rectangle) 的使用頻率甚至比畫線還要高。
無論是目標檢測中的邊界框(Bounding Box)、OCR識別中的文字區(qū)域高亮,還是隱私保護中的馬賽克遮擋,本質(zhì)上都是在畫矩形。
今天,我們將繼續(xù)使用 OpenCV 和 Pillow 這兩個利器,深入講解如何在 Python 中優(yōu)雅地畫矩形。
一、 為什么矩形如此重要?
- 目標檢測:YOLO、Faster R-CNN 等模型輸出的結(jié)果通常是矩形框坐標
(x, y, w, h)。 - ROI 提取:通過矩形框選感興趣區(qū)域(Region of Interest),進行裁剪或單獨處理。
- 數(shù)據(jù)脫敏:用矩形色塊覆蓋身份證號、車牌、人臉。
二、 核心參數(shù)解析
在開始寫代碼前,先記住畫矩形的幾個核心要素:
- 左上角坐標
(x1, y1) - 右下角坐標
(x2, y2)- 注意:有些庫也支持傳入
[x1, y1, x2, y2]列表。
- 注意:有些庫也支持傳入
- 顏色:RGB 或 BGR 元組。
- 線寬/填充:是只畫邊框,還是填充整個矩形?
三、 OpenCV 實現(xiàn):cv2.rectangle()
OpenCV 是計算機視覺的首選,它的 rectangle 函數(shù)非常高效,支持 numpy 數(shù)組操作。
1. 基礎(chǔ)用法:畫一個紅色邊框
import cv2
import numpy as np
# 創(chuàng)建一張黑色背景圖
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 設(shè)置為 -1 即可填充矩形。這常用于遮擋敏感信息。
# 畫一個綠色的實心矩形 cv2.rectangle(img, (50, 350), (450, 450), (0, 255, 0), -1)
B. 畫圓角矩形(OpenCV 沒有直接函數(shù),需要自己實現(xiàn))
OpenCV 原生不支持圓角矩形,但我們可以通過畫線和圓組合,或者用循環(huán)畫短線來模擬。這里教大家一個簡單的“偽圓角”方法:
# 簡單的圓角矩形函數(shù)
def draw_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 實現(xiàn):ImageDraw.rectangle()
Pillow 的 API 在處理坐標時更加靈活,支持直接傳入列表,且顏色是直觀的 RGB。
1. 基礎(chǔ)用法
from PIL import Image, ImageDraw
# 創(chuàng)建白色背景圖
img = Image.new('RGB', (500, 500), color='white')
draw = ImageDraw.Draw(img)
# 坐標可以是 [左上角x, 左上角y, 右下角x, 右下角y]
box = [50, 50, 400, 300]
# 畫藍色邊框,寬度為 3
draw.rectangle(box, outline='blue', width=3)
# 畫一個紅色實心矩形
draw.rectangle([50, 350, 450, 450], fill='red')
img.show()
2. Pillow 的獨特優(yōu)勢:支持多邊形裁剪
Pillow 的 rectangle 其實可以接受任意多邊形坐標(只要是矩形框選邏輯),或者配合 ImageDraw.polygon 使用更自由。
五、 實戰(zhàn)案例:三個高價值場景
場景 1:給檢測到的物體打標簽(帶文字的矩形)
在目標檢測中,我們通常在矩形上方貼一個帶背景色的文字標簽。
import cv2
img = cv2.imread("test.jpg") # 假設(shè)有一張原圖
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:高級馬賽克(網(wǎng)格狀矩形)
簡單的實心矩形太生硬,真正的馬賽克是由很多小矩形組成的。
def apply_mosaic(img, x, y, w, h, block_size=10):
"""
對指定區(qū)域 (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] = roi
return img
# 使用
img = cv2.imread("face.jpg")
img = apply_mosaic(img, 50, 50, 200, 200)
cv2.imshow("Mosaic", img)
cv2.waitKey(0)
注:雖然這用了 resize,但原理上是把像素塊變成了“大矩形”。
場景 3:半透明遮罩(Highlight)
有時候我們需要高亮某個區(qū)域,但又不想完全遮住原圖。
import cv2
import numpy as np
img = cv2.imread("test.jpg")
overlay = img.copy()
# 定義區(qū)域
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),向右下增長 |
| 參數(shù) | (img, pt1, pt2, color, thickness) | (xy, outline, fill, width) |
| 填充 | thickness = -1 | fill = 'color' |
| 性能 | 極快 (底層C++,支持Numpy) | 中等 (純Python實現(xiàn)部分) |
| 顏色 | BGR (易錯點) | RGB (直觀) |
| 推薦場景 | 視頻處理、實時檢測、算法開發(fā) | 批量圖片處理、Web后端生成圖 |
七、 總結(jié)
畫矩形看似簡單,但在實際應(yīng)用中往往需要結(jié)合坐標計算、顏色空間轉(zhuǎn)換和圖層混合。
- 如果你在做 YOLO/SSD 目標檢測 或 OpenCV 項目,請熟練掌握
cv2.rectangle,特別是利用-1做遮擋,利用addWeighted做半透明高亮。 - 如果你在做 Pillow 腳本 處理,記得它的參數(shù)更人性化,支持直接傳列表。
以上就是使用Python在圖片上畫矩形全攻略的詳細內(nèi)容,更多關(guān)于Python在圖片上畫矩形的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python視頻轉(zhuǎn)化字節(jié)問題的完整實現(xiàn)
在Python中可以將視頻和字節(jié)進行轉(zhuǎn)換,下面這篇文章主要給大家介紹了關(guān)于python視頻轉(zhuǎn)化字節(jié)問題的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-05-05
Python mutiprocessing多線程池pool操作示例
這篇文章主要介紹了Python mutiprocessing多線程池pool操作,結(jié)合實例形式分析了Python多線程模塊multiprocessing進程池相關(guān)操作技巧,需要的朋友可以參考下2019-01-01
Python使用BeautifulSoup提取網(wǎng)頁數(shù)據(jù)的完整指南
本文通過費曼學(xué)習法深入解析BeautifulSoup這一Python網(wǎng)頁解析神器,從基礎(chǔ)概念到實戰(zhàn)應(yīng)用,用通俗易懂的語言和豐富案例幫助讀者掌握HTML解析技術(shù),文章涵蓋BeautifulSoup的核心原理、解析器選擇、元素定位方法、數(shù)據(jù)提取技巧以及實際項目應(yīng)用,讓你快速成為網(wǎng)頁數(shù)據(jù)提取專家2025-07-07
caffe的python接口deploy生成caffemodel分類新的圖片
這篇文章主要為大家介紹了caffe的python接口生成deploy文件學(xué)習以及用訓(xùn)練好的模型(caffemodel)來分類新的圖片示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06

