更新於 2024/07/20閱讀時間約 4 分鐘

[Python][OpenCV]防止擷取圖像時超過範圍報錯

在影像處理中,有時候我們只想特別關注某個感興趣的區域時,就是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)

詳細說明

  1. max(y, 0)
    • 這部分確保 y 的值至少是 0。如果 y 的值小於 0,則取 0,否則取 y。
    • 換句話說,這是用來防止 y 的值變得太小(負數)。
    • 示例:pythonCopy codey = -5 max(y, 0) # 结果是 0 y = 10 max(y, 0) # 结果是 10
  2. min(..., img_h - 1)
    • 這部分確保 y 的值不超過 img_h - 1。img_h 是圖像的高度,img_h - 1 是圖像中最後一行的索引。
    • 換句話說,這是用來防止 y 的值超出圖像的範圍。

結合起來的效果

這兩個操作結合起來,確保 y 的值始終在 0img_h - 1 之間:

  • 如果 y 小於 0,結果是 0
  • 如果 y 大於或等於 img_h,結果是 img_h - 1
  • 如果 y0img_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

用途

這種做法在圖像處理中非常常見,用來確保像素索引不超出圖像的邊界,防止程式崩潰或引發錯誤。

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.