文、意如
續上一篇:[AI][Python]OpenCV進行臉部偵測(取得臉部座標位置)

py07.py
import cv2 # 匯入 OpenCV 函式庫,用於影像處理
# 讀取彩色圖片(BGR格式)
img = cv2.imread('media/img3.jpg') # 注意:需確認圖片路徑正確
# 顯示原圖的形狀(高度, 寬度, 色彩通道數)
print("img.shape=", img.shape) # 例如:img.shape= (339, 755, 3)
# 顯示原始圖片視窗
cv2.imshow('Original Image', img)
# 指定臉部位置與大小(手動設定,未使用自動臉部偵測)
x, y, w, h = 272, 52, 143, 143 # (左上角座標x, y) + 寬度、高度
# 擷取臉部區域的圖像資料,取用 [y座標範圍, x座標範圍]
face = img[y:y+h, x:x+w]
# ========= 開始進行馬賽克處理 =========
# 設定馬賽克像素大小(值越大,模糊程度越高)
mosaic_size = 10
# 將臉部圖像縮小成 mosaic_size 的比例(例如變成 14x14 像素)
# INTER_LINEAR:較平滑的縮小方式
small = cv2.resize(face, (w // mosaic_size, h // mosaic_size), interpolation=cv2.INTER_LINEAR)
# 將剛剛縮小後的圖,再放大回原本大小
# INTER_NEAREST:放大時保留像素邊界(看起來更像馬賽克)
mosaic_face = cv2.resize(small, (w, h), interpolation=cv2.INTER_NEAREST)
# 將處理後的馬賽克臉部,覆蓋回原圖的臉部位置
img[y:y+h, x:x+w] = mosaic_face
# ========= 馬賽克處理完成 =========
# 顯示處理後的圖片視窗
cv2.imshow("Mosaic Face", img)
# 等待任意鍵按下後,關閉所有 OpenCV 視窗
cv2.waitKey(0)
cv2.destroyAllWindows()
補充說明:
語法 | 說明 |
---|---|
cv2.imread() | 讀取圖片,第 2 個參數預設為 1(彩色) |
img[y:y+h, x:x+w] | 取出圖像的區域(臉的矩形範圍) |
cv2.resize() | 調整影像大小,這裡先縮小再放大產生像素化效果 |
INTER_LINEAR | 插值方式,適合縮小 |
INTER_NEAREST | 插值方式,適合放大馬賽克效果 |
cv2.imshow() | 顯示圖片視窗 |
cv2.waitKey(0) | 等待任意鍵按下 |
cv2.destroyAllWindows() | 關閉所有視窗 |
進階應用:
✅ 自動偵測多張人臉 → 對每一張臉都打馬賽克
✅ 為每張人臉加上綠色框線與提示文字
✅ 將結果圖片儲存為 output.jpg
功能 | 描述 |
---|---|
detectMultiScale() | 自動偵測圖片中的所有人臉 |
cv2.rectangle() | 繪製臉部框線 |
cv2.putText() | 加上提示文字 |
cv2.imwrite() | 將處理後的圖片儲存到本地 |

py08.py
import cv2 # 匯入 OpenCV 函式庫(用於影像處理與電腦視覺)
# 載入 OpenCV 內建的人臉特徵分類器 XML(包含各種臉部特徵)
case_path = cv2.data.haarcascades + "haarcascade_frontalface_default.xml"
face_cascade = cv2.CascadeClassifier(case_path)
# 讀取一張圖片(以 BGR 彩色模式)
img = cv2.imread('media/img4.jpg') # 可替換為你的圖片路徑
# 將彩色圖片轉成灰階(偵測速度更快)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 使用分類器偵測臉部
faces = face_cascade.detectMultiScale(
gray, # 傳入灰階圖像
scaleFactor=1.1, # 每次影像縮小的比例(>1,數字越小檢測越仔細但越慢)
minNeighbors=5, # 最小鄰近數,數字越大越嚴格(建議 3~6)
minSize=(30, 30) # 臉部的最小尺寸(小於這個尺寸的不會被偵測)
)
# 印出偵測到幾張人臉
print(f"共偵測到 {len(faces)} 張人臉")
# 遍歷每一張臉,進行處理
for i, (x, y, w, h) in enumerate(faces):
# 繪製綠色的矩形框,框住臉部
# (x, y):左上角座標,(x+w, y+h):右下角座標,(0, 255, 0):綠色,2:線條粗細
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 從原圖中擷取臉部區域(y:高度, x:寬度)
face = img[y:y + h, x:x + w]
# ----------- 進行「馬賽克處理」 -------------
mosaic_size = 10 # 馬賽克的強度(越大越模糊)
# 將臉部縮小
small = cv2.resize(face, (w // mosaic_size, h // mosaic_size), interpolation=cv2.INTER_LINEAR)
# 再放大回原尺寸(會變成像素狀)
mosaic_face = cv2.resize(small, (w, h), interpolation=cv2.INTER_NEAREST)
# 將原本臉部區域替換為馬賽克後的區塊
img[y:y + h, x:x + w] = mosaic_face
# ----------- 顯示臉部的提示文字 -------------
text = f"Face {i + 1}" # 顯示:Face 1、Face 2…
font = cv2.FONT_HERSHEY_SIMPLEX # 使用內建英文字型
font_scale = 0.6 # 文字大小
thickness = 2 # 文字線條粗細
color = (200, 200, 200) # 文字顏色(灰白)
# 計算文字位置:臉部上方,避免太靠上
text_size, _ = cv2.getTextSize(text, font, font_scale, thickness)
text_x = x
text_y = y - 10 if y - 10 > 20 else y + 20
# 加入提示文字
cv2.putText(img, text, (text_x, text_y), font, font_scale, color, thickness)
# ----------- 在右下角加上總人臉數 -------------
face_count_text = f"Detected {len(faces)} face(s)"
text_size, _ = cv2.getTextSize(face_count_text, cv2.FONT_HERSHEY_SIMPLEX, 0.7, 2)
text_x = img.shape[1] - text_size[0] - 10 # 右邊留 10px 邊界
text_y = img.shape[0] - 10 # 底部留 10px 邊界
cv2.putText(img, face_count_text, (text_x, text_y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
# ----------- 儲存處理後的圖片 -------------
cv2.imwrite("output.jpg", img) # 將結果儲存為檔案
print("圖片已儲存為 output.jpg")
# ----------- 顯示處理後的圖片視窗 -------------
cv2.imshow("Face Mosaic", img) # 視窗名稱 + 圖片內容
cv2.waitKey(0) # 等待任意鍵結束
cv2.destroyAllWindows() # 關閉所有 OpenCV 視窗
讓使用者自行選擇圖片


py09.py
import cv2 # 匯入 OpenCV 函式庫(用於影像處理與電腦視覺)
from tkinter import Tk
from tkinter.filedialog import askopenfilename
# 關閉預設的 Tkinter 視窗
Tk().withdraw()
# 彈出檔案選擇對話框
file_path = askopenfilename(title="請選擇圖片", filetypes=[("Image files", "*.jpg *.png *.jpeg *.bmp")])
# 判斷是否有選擇檔案
if not file_path:
print("未選擇圖片,程式結束。")
exit()
# 讀取使用者選擇的圖片,後續圖像處理就可以繼續使用 img
img = cv2.imread(file_path)
if img is None:
print("圖片讀取失敗")
exit()
# 載入 OpenCV 內建的人臉特徵分類器 XML(包含各種臉部特徵)
case_path = cv2.data.haarcascades + "haarcascade_frontalface_default.xml"
face_cascade = cv2.CascadeClassifier(case_path)
# 將彩色圖片轉成灰階(偵測速度更快)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 使用分類器偵測臉部
faces = face_cascade.detectMultiScale(
gray, # 傳入灰階圖像
scaleFactor=1.1, # 每次影像縮小的比例(>1,數字越小檢測越仔細但越慢)
minNeighbors=5, # 最小鄰近數,數字越大越嚴格(建議 3~6)
minSize=(30, 30) # 臉部的最小尺寸(小於這個尺寸的不會被偵測)
)
# 印出偵測到幾張人臉
print(f"共偵測到 {len(faces)} 張人臉")
# 遍歷每一張臉,進行處理
for i, (x, y, w, h) in enumerate(faces):
# 繪製綠色的矩形框,框住臉部
# (x, y):左上角座標,(x+w, y+h):右下角座標,(0, 255, 0):綠色,2:線條粗細
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 從原圖中擷取臉部區域(y:高度, x:寬度)
face = img[y:y + h, x:x + w]
# ----------- 進行「馬賽克處理」 -------------
mosaic_size = 10 # 馬賽克的強度(越大越模糊)
# 將臉部縮小
small = cv2.resize(face, (w // mosaic_size, h // mosaic_size), interpolation=cv2.INTER_LINEAR)
# 再放大回原尺寸(會變成像素狀)
mosaic_face = cv2.resize(small, (w, h), interpolation=cv2.INTER_NEAREST)
# 將原本臉部區域替換為馬賽克後的區塊
img[y:y + h, x:x + w] = mosaic_face
# ----------- 顯示臉部的提示文字 -------------
text = f"Face {i + 1}" # 顯示:Face 1、Face 2…
font = cv2.FONT_HERSHEY_SIMPLEX # 使用內建英文字型
font_scale = 0.6 # 文字大小
thickness = 2 # 文字線條粗細
color = (0, 0, 0) # 文字顏色(灰白)
# 計算文字位置:臉部上方,避免太靠上
text_size, _ = cv2.getTextSize(text, font, font_scale, thickness)
text_x = x
text_y = y - 10 if y - 10 > 20 else y + 20
# 加入提示文字
cv2.putText(img, text, (text_x, text_y), font, font_scale, color, thickness)
# ----------- 在右下角加上總人臉數 -------------
face_count_text = f"Detected {len(faces)} face(s)"
text_size, _ = cv2.getTextSize(face_count_text, cv2.FONT_HERSHEY_SIMPLEX, 0.7, 2)
text_x = img.shape[1] - text_size[0] - 10 # 右邊留 10px 邊界
text_y = img.shape[0] - 10 # 底部留 10px 邊界
cv2.putText(img, face_count_text, (text_x, text_y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)
# ----------- 儲存處理後的圖片 -------------
cv2.imwrite("output.jpg", img) # 將結果儲存為檔案
print("圖片已儲存為 output.jpg")
#調整顯示圖片的尺寸
max_width = 800
if img.shape[1] > max_width:
scale = max_width / img.shape[1]
resized_img = cv2.resize(img, (int(img.shape[1] * scale), int(img.shape[0] * scale)))
else:
resized_img = img
# ----------- 顯示處理後的圖片視窗 -------------
cv2.imshow("Face Mosaic", resized_img) # 視窗名稱 + 圖片內容
cv2.waitKey(0) # 等待任意鍵結束
cv2.destroyAllWindows() # 關閉所有 OpenCV 視窗
讓使用者進行選擇圖片

py10.py
import cv2
import tkinter as tk
from tkinter import filedialog
import numpy as np
def select_image():
# 使用者選圖
filepath = filedialog.askopenfilename(filetypes=[("Image files", "*.jpg *.png *.jpeg")])
if not filepath:
print("沒有選擇圖片")
return
# 安全讀取圖片(防止中文/空白路徑失敗)
with open(filepath, 'rb') as f:
img_array = np.asarray(bytearray(f.read()), dtype=np.uint8)
img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
if img is None:
print("圖片讀取失敗")
return
# 圖片縮小(避免過大閃退)
max_width = 800
scale = max_width / img.shape[1]
img = cv2.resize(img, (int(img.shape[1]*scale), int(img.shape[0]*scale)))
# 載入人臉偵測模型
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
# 灰階轉換提升效能
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 偵測人臉
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
for (x, y, w, h) in faces:
# 取出臉部區域
face_roi = img[y:y+h, x:x+w]
# 打馬賽克:縮小再放大
mosaic = cv2.resize(face_roi, (16, 16), interpolation=cv2.INTER_LINEAR)
mosaic = cv2.resize(mosaic, (w, h), interpolation=cv2.INTER_NEAREST)
img[y:y+h, x:x+w] = mosaic
# 畫出綠色框線
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
# 上方加灰色提示框 + 文字
label = "face"
(tw, th), _ = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.6, 2)
cv2.rectangle(img, (x, y-25), (x + tw + 10, y), (128, 128, 128), -1)
cv2.putText(img, label, (x + 5, y - 7), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 2)
# 顯示總數
count_text = f"{len(faces)} faces"
(ctw, cth), _ = cv2.getTextSize(count_text, cv2.FONT_HERSHEY_SIMPLEX, 0.7, 2)
cx = img.shape[1] - ctw - 10
cy = img.shape[0] - 10
cv2.putText(img, count_text, (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
# 儲存圖片
cv2.imwrite("output.jpg", img)
print("已儲存為 output.jpg")
# 顯示圖片
cv2.imshow("馬賽克人臉", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# GUI 主畫面
root = tk.Tk()
root.title("人臉馬賽克工具")
root.geometry("300x100")
btn = tk.Button(root, text="選擇圖片並處理", command=select_image, font=("Arial", 14))
btn.pack(expand=True)
root.mainloop()
Yiru@Studio - 關於我 - 意如