【小林的OpenCV基礎課 5】圖像的基本操作
私は小林です、天気は最近寒いです
在這一話中,小林將會帶領同學們學習對圖像的基本操作。有多基本呢?如下:
- 獲取、修改像素值
- 獲取圖像基本屬性
- 設置ROI區域
- 分離、合併通道
呃,前兩條看起來比較容易,後面兩個是個啥?
既然同學們對後面兩個感興趣,那小林就從頭開始講(づ ̄ 3 ̄)づ。
獲取、修改像素值
不管是視頻也好,圖片也好,構成他們的基本元素就是像素(Pixel)。所有像素的像素值決定了畫面的樣子。一幅圖像的所有像素中可能有一個通道(如灰度圖像)也可能有多個通道(如BGR和HSV)。通常我們見到的彩色圖像通道數為3通道,數據類型為uint8(取值範圍0~255)。OpenCV中的RGB空間的默認通道順序不是RGB,而是BGR。
使用python的OpenCV中,獲取、修改像素值的方法常用的有兩種:
- 從矩陣直接獲取
- 通過numpy的函數從矩陣中間接獲取(需導入numpy模塊)
首先使用imread導入圖像。
直接獲取並修改的代碼如下:
# 獲取三通道像素值npix_bgr = img[100,100]nprint(pix_bgr)n# 獲取g通道像素值npix_g = img[100,100,1]nprint(pix_g)n# 在矩陣中直接修改像素值nimg[100,100] = [122,122,122]n
間接獲取和修改的代碼如下:
# 使用numpy的item方法獲取像素npix = img.item(100,100,2)nprint(pix)n# 使用numpy的itemset方法修改像素nimg.itemset((100,100,1),255)n
註:在訪問像素值方面,python要比C++簡單,不需要考慮煩人的指針啥的。
獲取圖像基本屬性
通過訪問矩陣的成員變數獲取圖像的基本屬性。代碼如下:
# 獲取長寬和通道數nprint(img.shape)n# 獲取像素總數 長*寬*通道數nprint(img.size)n# 獲取像素的數據類型nprint(img.dtype)n
設置ROI區域
何為ROI區域?ROI就是Region Of Interest,感興趣區域。比如說,如果有一張托爾醬的全身照,有些人會關注尾巴,有些人則會關注(一些不可描述的地方)。換言之,當需要研究圖像中我們感興趣的部分時,就需要框定ROI區域了。如下:
ROI = img[200:399, 480:639]n
可以看出,ROI實際上是整個圖像矩陣中的一部分,本質上也是矩陣,就像在托爾醬的尾巴上用紅筆畫了一個框,告訴人們我們要重點研究尾巴(研究尾巴肉怎麼做才好吃嗎?)
關於ROI,其實有個小小的坑,涉及到矩陣的引用和複製的問題,可以使用numpy中相關的函數來填上這個坑,具體實現在本節的示例代碼中。
分離、合併通道
依舊是通道。通過split和merge函數可分別實現通道的分離和合併,有助於我們研究單個通道。
函數原型:
mv = cv2.split(m[, mv])n
- m:需要被分離的圖像矩陣
- mv:分離後的通道圖像矩陣,m為多通道時mv通常為通道向量
dst = cv2.merge(mv[, dst])n
- mv:需要被合併的通道向量
- dst:合併後的矩陣
敲黑板了:split和merge都是在當前的色彩空間中使用的,若需轉換色彩空間需使用函數cvtColor,函數原型:
dst = cv2.cvtColor(src, code[, dst[, dstCn]])n
- src:需要被轉換的圖像矩陣
- dst:轉換後的圖像矩陣
- code:色彩空間轉換標識代碼,常用的有BGR到灰度、BGR和HSV的互換,全部標識代碼可查閱API
- dstCn:轉換後的圖像矩陣的通道數,為0時會被自動確定,通常我們會省略這個參數
下面祭出人見人愛的香菜大姐姐(づ ̄ 3 ̄)づ:
import cv2nimport numpy as npnnimg = cv2.imread(hzxc2.jpg,1)nn# 分離圖像 得到BGR三個通道的圖像分量nb,g,r = cv2.split(img)nn# 顯示原圖和三個通道ncv2.namedWindow(Source Image)ncv2.namedWindow(Blue Channel)ncv2.namedWindow(Green Channel)ncv2.namedWindow(Red Channel)ncv2.imshow(Source Image, img)ncv2.imshow(Blue Channel, b)ncv2.imshow(Green Channel, g)ncv2.imshow(Red Channel, r)nn# 轉換為HSV色彩空間nhsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)n# 分離HSV三通道nh,s,v = cv2.split(hsv)n# 顯示原圖和三個通道ncv2.namedWindow(HSV)ncv2.namedWindow(H)ncv2.namedWindow(S)ncv2.namedWindow(V)ncv2.imshow(HSV, hsv)ncv2.imshow(H, h)ncv2.imshow(S, s)ncv2.imshow(V, v)ncv2.waitKey(0)ncv2.destroyAllWindows()n
畫面辣眼睛,小林就不放效果圖了。圖片在Github中,同學們也可以嘗試其他圖片哦。
作業又來啦,煩人
為了鞏固這一話的知識,請同學們嘗試:
- 改變小林自拍照中門鈴的顏色,要求使用ROI和BGR三通道,自拍照就是Github中的"IMG_8257.JPG"。
作業的示例代碼會在下一話更新時同步到Github。
本話的示例代碼已同步到Github中:本節示例代碼。在Class 3 Core Operations里,對應C3 Get Pixel.py、 C3 ROI.py和C3 Split and Merge Channel.py。
最後的最後
如果喜歡小林的專欄,就收藏了吧!してください!
推薦閱讀: