一、環境準備
import cv2
import numpy as np
import matplotlib.pyplot as plt# 配置中文字體顯示(可選)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
二、圖像的基本操作
1. 圖像讀取、顯示與保存
使用OpenCV操作
# 讀取圖像(支持多種格式)
img = cv2.imread('example.jpg')
print(f"圖像尺寸: {img.shape}") # 輸出:(高度, 寬度, 通道數)# 顯示圖像
cv2.imshow('OpenCV Window', img)
cv2.waitKey(0) # 等待按鍵
cv2.destroyAllWindows()# 保存圖像
cv2.imwrite('output.jpg', img) # 自動保存為JPG格式
使用Matplotlib操作
# 讀取并顯示圖像
plt.figure(figsize=(10,5))
img_plt = plt.imread('example.png') # 自動歸一化到[0,1]
plt.subplot(121)
plt.imshow(img_plt)
plt.title('Matplotlib顯示')# OpenCV與Matplotlib顏色空間差異
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # BGR轉RGB
plt.subplot(122)
plt.imshow(img_rgb)
plt.title('OpenCV轉RGB顯示')
plt.show()
?? 注意事項:
- OpenCV讀取的像素值范圍是[0,255],Matplotlib自動歸一化到[0,1]
- 路徑含中文時需使用
cv2.imdecode
特殊處理- 保存質量可通過參數控制(如
cv2.imwrite('out.jpg', img, [int(cv2.IMWRITE_JPEG_QUALITY), 90])
)
2. 像素級操作
單個像素訪問與修改
# 訪問特定位置像素值
px = img[100, 50] # 獲取坐標(50,100)處像素值
print(f"Blue={px[0]}, Green={px[1]}, Red={px[2]}")# 修改像素值
img[100, 50] = [0, 255, 0] # 將該位置改為綠色
區域像素操作
# 提取ROI區域(感興趣區域)
roi = img[50:150, 100:200]# 批量修改像素值
img[200:300, 300:400] = [0, 0, 255] # 填充紅色矩形
像素值統計分析
print(f"最大像素值: {img.max()}")
print(f"最小像素值: {img.min()}")
print(f"平均像素值: {img.mean()}")
3. 通道操作
通道分離與合并
# 分離通道(OpenCV方式)
b, g, r = cv2.split(img)
cv2.imshow('Blue Channel', b)# 合并通道
merged = cv2.merge([b, g, r])# 直接操作特定通道(Numpy方式)
img_copy = img.copy()
img_copy[:, :, 0] = 0 # 清空藍色通道
多光譜分析示例
# 顯示各通道灰度圖
plt.figure(figsize=(12, 3))
for i, ch in enumerate(['Blue', 'Green', 'Red']):plt.subplot(1,3,i+1)plt.imshow(cv2.split(img)[i], cmap='gray')plt.title(f'{ch}通道')plt.axis('off')
plt.show()
三、完整實踐案例
def image_processing_pipeline(path):# 1. 圖像讀取src = cv2.imread(path)if src is None:print("錯誤:無法讀取圖像!")return# 2. 通道分析b, g, r = cv2.split(src)# 3. 創建特殊效果special_effect = src.copy()special_effect[:, :, 1] = cv2.add(special_effect[:, :, 1], 50) # 增強綠色通道# 4. 結果展示plt.figure(figsize=(15, 5))plt.subplot(141)plt.imshow(cv2.cvtColor(src, cv2.COLOR_BGR2RGB))plt.title('原圖')plt.subplot(142)plt.imshow(r, cmap='gray')plt.title('紅色通道')plt.subplot(143)plt.imshow(special_effect[:, :, [2,1,0]])plt.title('增強綠色通道')plt.subplot(144)plt.imshow(b, cmap='viridis') # 使用不同色圖plt.title('藍色通道(Viridis色圖)')plt.tight_layout()plt.show()# 執行處理流程
image_processing_pipeline('test_image.jpg')
四、性能優化技巧
- 向量化操作替代循環:
# 推薦方式(Numpy向量化)
start_time = cv2.getTickCount()
brighter = cv2.add(img, np.array([30]))
print(f"耗時:{(cv2.getTickCount() - start_time)/cv2.getTickFrequency():.4f}s")# 不推薦方式(雙重循環)
start_time = cv2.getTickCount()
for y in range(img.shape[0]):for x in range(img.shape[1]):img[y,x] = np.clip(img[y,x] + 30, 0, 255)
print(f"耗時:{(cv2.getTickCount() - start_time)/cv2.getTickFrequency():.4f}s")
- 內存連續性優化:
# 檢查數組內存布局
if not img.flags.c_contiguous:img = np.ascontiguousarray(img)
五、常見問題解決方案
-
圖像無法顯示:
- 檢查路徑是否包含中文/特殊字符
- 確認圖像尺寸是否超過屏幕分辨率
- 嘗試使用
cv2.resizeWindow()
調整窗口大小
-
顏色顯示異常:
# 統一顏色空間轉換 def show_image統一(img_bgr, title='Image'):plt.imshow(cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB))plt.title(title)plt.axis('off')plt.show()
-
大圖像處理:
# 金字塔下采樣 pyramid = cv2.pyrDown(img) print(f"下采樣后尺寸:{pyramid.shape}")
六、擴展學習方向
-
進階操作:
- 使用
cv2.LUT()
實現色彩查找表變換 - 掩膜操作(mask)進行區域處理
- 利用Numpy數組的布爾索引進行條件修改
- 使用
-
性能提升:
- 使用OpenCV內置函數替代Python循環
- 多線程處理圖像塊
- CUDA加速(需安裝opencv-contrib-python包)
-
實際應用:
- 圖像增強:直方圖均衡化、CLAHE算法
- 顏色空間轉換:HSV/YUV等
- 形態學操作:腐蝕、膨脹
通過掌握這些基礎操作,您將為后續的圖像處理學習打下堅實基礎。建議通過實際項目(如證件照背景替換、圖像特效制作)加深理解。
下一篇我們將進入圖像的「幾何變換世界」,學習如何用數學矩陣實現圖像的平移、旋轉、縮放,以及不同插值算法對圖像質量的影響。現在請打開你的圖像,嘗試裁剪一個有趣的ROI區域并修改它的顏色吧!
思考:為什么對大尺寸圖像使用
cv2.split()
會更耗內存?如何用NumPy實現更高效的通道分離?