【第六節(jié)】圖像的基礎(chǔ)操作
目標(biāo)
獲取像素值并修改
獲取圖像的屬性(信息)
圖像的ROI()
圖像通道的拆份及合并
幾乎所有這些操作與Numpy的關(guān)系都比與OpenCV的關(guān)系更加緊密,因此熟練Numpy可以幫助我們寫出性能更好的代碼。
1、獲取并修改像素值
首先,我們需要讀入一幅圖像:
????????你可以根據(jù)像素的行和列的坐標(biāo)獲取他的像素值。對(duì)BGR圖像而言,返回值為B,G,R的值。對(duì)灰度圖像而言,會(huì)返回他的灰度值
你可以以類似的方式修改像素值
警告:Numpy是經(jīng)過(guò)優(yōu)化了的進(jìn)行快速矩陣運(yùn)算的軟件包。所以我們不推薦逐個(gè)獲取像素值并修改,這樣會(huì)很慢,能有矩陣運(yùn)算就不要用循環(huán)。
注意:上面提到的方法被用來(lái)選取矩陣的一個(gè)區(qū)域,比如說(shuō)前5行的后3列。對(duì)于獲取每一個(gè)像素值,也許使用Numpy的array.item() 和array.itemset()會(huì)更好。但是返回值是標(biāo)量。如果你想獲得所有B, G, R的值,你需要使用array.item()分割他們。
獲取像素值及修改的更好方法:
2、獲取圖像屬性
????????圖像的屬性包括:行,列,通道,圖像數(shù)據(jù)類型,像素?cái)?shù)目等
img.shape可以獲取圖像的形狀。他的返回值是一個(gè)包含行數(shù)、列數(shù)、通道數(shù)的元組。
注意:如果圖像是灰度圖,返回值僅有行數(shù)和列數(shù)。所以通過(guò)檢查這個(gè)返回值就可以知道加載的是灰度圖還是彩色圖。
img.size還可以返回圖像的像素?cái)?shù)目:
img.dtype返回的是圖像的數(shù)據(jù)類型
注意:在debug時(shí),img.dtype非常重要。因?yàn)樵贠penCV-python中經(jīng)常會(huì)出現(xiàn)數(shù)據(jù)類型的不一致。
3、圖像的ROI
????????有時(shí)你需要對(duì)一幅圖像的特定區(qū)域進(jìn)行操作。例如我們要檢測(cè)一副圖像中眼睛的位置,我們首先應(yīng)該在圖像中找到臉,再在臉的區(qū)域中找眼睛,而不是直接在一幅圖像中搜索。這樣會(huì)提高程序的準(zhǔn)確性和性能。
????????ROI也是使用Numpy索引來(lái)獲得的?,F(xiàn)在我們選擇眼睛的部分并把他拷貝到圖像的其他區(qū)域。
看看結(jié)果吧:

4、拆份及合并圖像通道
????????有時(shí)我們需要對(duì)BGR三個(gè)通道分別進(jìn)行操作。這是你就需要把BGR拆分成單個(gè)通道。有時(shí)你需要把獨(dú)立通道的圖片合并成一個(gè)BGR圖像。你可以這樣做:
或者
????????假如你想使所有像素的紅色通道值都為0,你不必拆分在賦值。可以直接使用Numpy索引,這會(huì)更快。
警告:CV2.split()是一個(gè)比較耗時(shí)的操作。只有真正需要時(shí)才用它,能用Numpy索引就盡量用。
5、為圖像擴(kuò)邊(填充)
????????如果你想在圖像周圍創(chuàng)建一個(gè)邊 ,就像相框一樣,你可以使用CV2.copyMakeBorder()函數(shù)。這經(jīng)常在卷積運(yùn)算或0填充時(shí)被用到。這個(gè)函數(shù)包括如下參數(shù):
src輸入圖像
top, bottom, left, right對(duì)應(yīng)邊界的像素?cái)?shù)目。
borderType要添加那種類型的邊界,類型如下
????????????- CV2.BORDER_ CONSTANT添加有顏色的常數(shù)值邊界,還需要下一個(gè)參數(shù)( value )。
????????????- CV2.BORDER_ REFLECT邊界元素的鏡像。比如: fedcba|abcde-fgh|hgfedcb
????????????- CV2.BORDER_ REFLECT_ 101 or CV2.BORDER_ DEFAULT跟上面一樣,但稍作改? ? ? ? ? ? ? 動(dòng)。例如: gfedcb|abcdefgh|gfedcba
????????????- CV2.BORDER REPLICATE重復(fù)最后一個(gè)元素。例如: aaaaaa|
????????????abcdefgh|hhhhhhh
????????????- CV2.BORDER _WRAP不知道怎么說(shuō)了,就像這樣: cdefgh|abcdefghlabcdefg
value邊界顏色,如果邊界的類型是CV2.BORDER CONSTANT
為了更好理解這幾種類型,請(qǐng)看下面的演示程序。
結(jié)果如下(由于是使用matplotlib繪制,所以交換R和B的位置,OpenCV中是按BGR, matplotlib 中是按RGB排列):

上圖效果看的可能不清晰,換一個(gè)圖片再看看:
