opencv入門系列教學(五)影像的基本操作(像素值、屬性、ROI和邊框)
- 2021 年 8 月 30 日
- 筆記
- openCV入門系列教學
0.序言
每個影像是由一個個點組成的,而這些點可以表示為像素值的形式。
這篇部落格里我們將學會:
- 訪問像素值並修改它們 。
- 訪問影像屬性 。
- 設置感興趣區域(ROI) 。
- 分割和合併影像。
對於影像的基本操作我們需要對numpy知識的了解,不需要很多,只知道基本用法即可。這裡暫不贅述,讀者可查閱其餘資料進行學習。
1.訪問和修改像素值
讓我們先載入彩色影像:
我們可以通過行和列坐標來訪問像素值。對於 BGR 影像,它返回一個由藍色、綠色和紅色值組成的數組。而如果是灰度影像的話,它只返回相應的灰度。我們也可以用相同的方式來對像素值進行修改。
Numpy是用於快速數組計算的優化庫。因此,簡單地訪問每個像素值並對其進行修改將非常慢,因此不建議使用。對於單個像素訪問,Numpy數組方法array.item()和array.itemset())被認為更好,但是它們始終返回標量。如果要訪問所有B,G,R值,則需要分別調用所有的array.item()。
比如我們可以用下面的方法來進行像素的訪問和編輯:
2.訪問影像屬性
影像屬性包括行數,列數,通道數,影像數據類型,像素數等等。
影像的形狀可通過 img.shape 訪問。它返回行,列和通道數的元組(如果影像是彩色的)
注意:如果影像是灰度的,則返回的元組僅包含行數和列數,因此這是檢查載入的影像是灰度還是彩色的好方法。
像素總數可通過訪問 img.size :
影像數據類型通過 img.dtype 獲得:
注意:img.dtype在調試時非常重要,因為OpenCV-Python程式碼中的大量錯誤是由無效的數據類型引起的。
3.影像感興趣區域ROI
有時候,我們不得不處理一些特定區域的影像。比如對於影像中的眼睛檢測,首先對整個影像進行人臉檢測。在獲取人臉影像時,我們只選擇人臉區域,搜索其中的眼睛,而不是搜索整個影像。它提高了準確性和性能。
這裡我們直接使用numpy的切片即可,比如:
不規則形狀的ROI區域的設置,我們將在以後的文章里再詳細闡述。
4.拆分和合併影像通道
有時我們需要分別處理影像的B,G,R通道。在這種情況下,我們需要將BGR影像拆分為單個通道。我們可以這樣做:
但是cv.split() 是一項耗時的操作(就時間而言)。因此,僅在必要時才這樣做。我們一般採用Numpy索引的方法。比如我們要將所有的紅色像素都設置為0:
5.為影像設置邊框
如果我們要在影像周圍創建邊框(如相框),那可以使用 cv.copyMakeBorder() 。它在以後對影像進行高級處理的時候,比如卷積運算,零填充等方面將有更多應用。此函數採用以下參數:
- src – 輸入影像
- top,bottom,left,right 邊界寬度(以相應方向上的像素數為單位)
- borderType – 定義要添加哪種邊框的標誌。它可以是以下類型:
- cv.BORDER_CONSTANT – 添加恆定的彩色邊框。該值應作為下一個參數給出。
- cv.BORDER_REFLECT – 邊框將是邊框元素的鏡像,如下所示: fedcba | abcdefgh hgfedcb
- **cv.BORDER_REFLECT_101**或 **cv.BORDER_DEFAULT**與上述相同,但略有變化,例如: gfedcb | abcdefgh | gfedcba
- **cv.BORDER_REPLICATE**最後一個元素被複制,像這樣: aaaaaa | abcdefgh | hhhhhhh
- **cv.BORDER_WRAP**看起來像這樣: cdefgh | abcdefgh | abcdefg
- value -邊框的顏色,如果邊框類型為**cv.BORDER_CONSTANT**
下面我們來看一下各個邊框類型在圖片顯示上的結果。注意因為影像是基於matplotlib一起顯示的。所以紅色和藍色通道將會互換。
結果如下: