在影像處理中,有時候我們只想特別關注某個感興趣的區域時,就是ROI的概念,擷取此範圍的圖像來做處理。
設定超過圖像邊界時就會報錯,本文主要介紹如何擷取影像的同時,避免設定錯誤造成程式崩潰的狀況。
擷取圖像示意圖

ROI程式範例
import cv2
import numpy as np
img = cv2.imread(f'圖片路徑')
# 擷取範圍
y = 200
x = 200
h = 200
w = 200
y_ = y + h
x_ = x + w
#擷取圖片
roi = img[y:y_, x:x_]
#顯示圖片
cv2.imshow('roi',roi)
cv2.waitKey(0)
cv2.destroyAllWindows()
當X或Y設定超過原先圖片邊界時就會報錯。
先印出圖片大小,故意設定超過圖像邊界,圖像高度420,Y設定超過420就會報錯
img_h, img_w = img.shape[:2]
print(f'img_h : {img_h}, img_w: {img_w}')
# 擷取範圍
y = 440
x = 200
h = 200
w = 200
y_ = y + h
x_ = x + w

如何避免超過邊界報錯
在第17,18加入了偵測的功能,限制Y與X輸出的範圍,即使Y輸入,他也會限制其範圍將數值鎖定在圖片高度-1的況狀下,也就是419,我們把Y印出就會是419這數值。
import cv2
import numpy as np
img = cv2.imread(f'圖片路徑')
img_h, img_w = img.shape[:2]
print(f'img_h : {img_h}, img_w: {img_w}')
# 擷取範圍
y = 440
x = 200
h = 200
w = 200
y_ = y + h
x_ = x + w
# 避免超過範圍變成空的
y = min(max(y, 0), img_h - 1)
x = min(max(x, 0), img_w - 1)
print(f'y : {y}')
print(f'x : {x}')
# 擷取圖片
roi = img[y:y_, x:x_]
# 顯示圖片
cv2.imshow('roi',roi)
cv2.waitKey(0)
cv2.destroyAllWindows()

關鍵語法說明
y = min(max(y, 0), img_h - 1)
詳細說明
- max(y, 0):
- 這部分確保 y 的值至少是 0。如果 y 的值小於 0,則取 0,否則取 y。
- 換句話說,這是用來防止 y 的值變得太小(負數)。
- 示例:pythonCopy codey = -5 max(y, 0) # 结果是 0 y = 10 max(y, 0) # 结果是 10
- min(..., img_h - 1):
- 這部分確保 y 的值不超過 img_h - 1。img_h 是圖像的高度,img_h - 1 是圖像中最後一行的索引。
- 換句話說,這是用來防止 y 的值超出圖像的範圍。
結合起來的效果
這兩個操作結合起來,確保 y
的值始終在 0
和 img_h - 1
之間:
- 如果
y
小於0
,結果是0
。 - 如果
y
大於或等於img_h
,結果是img_h - 1
。 - 如果
y
在0
到img_h - 1
之間,結果就是y
本身。
範例
假設圖像的高度為 100
:
img_h = 100
y = -10
y = min(max(y, 0), img_h - 1) # y 變為 0
y = 50
y = min(max(y, 0), img_h - 1) # y 保持 50
y = 120
y = min(max(y, 0), img_h - 1) # y 變為 99
用途
這種做法在圖像處理中非常常見,用來確保像素索引不超出圖像的邊界,防止程式崩潰或引發錯誤。