·訪問像素值并修改它們
·訪問圖片屬性
·設(shè)置ROI
·分割和合并圖片
基本上本節(jié)所有的操作都是和Numpy相關(guān)的而不是OpenCV
訪問和修改像素值
讓我們加載一張彩色圖片:
>>>import cv2
>>>import numpy as np
>>>img = cv2.imread('messi5.jpg')
你可以通過行和列坐標(biāo)訪問一個(gè)像素值。對于BGR圖片檩禾,它會返回一個(gè)藍(lán)寸莫,綠申屹,紅值的數(shù)組。對于灰度圖片辆床,只會返回對應(yīng)的深度。
>>>px = img[100,100]
>>>print px[157 166 200]
# accessing only blue pixel
>>>blue = img[100,100,0]
>>>print blue
157
你可以修改這個(gè)像素值:
>>>img[100,100] = [255,255,255]
>>>print img[100,100]
[255 255 255]
警告:
Numpy是一個(gè)優(yōu)化的庫,能夠快速計(jì)算數(shù)組瑟由。所以如果一個(gè)個(gè)訪問每個(gè)像素并修改它的值是很慢的,也不推薦
注意:
一般來說冤寿,都是選擇數(shù)組的一片區(qū)域歹苦,比如頭5行或者最后三列。對于某個(gè)像素點(diǎn)的訪問督怜,Numpy數(shù)組方法殴瘦,array.item() 和array.itemset()更好。但是它總是返回標(biāo)量号杠。所以如果你想訪問所有的B, G, R值蚪腋,你需要分開調(diào)用array.item()
更好的訪問和編輯方式:
# accessing RED value
>>>img.item(10,10,2)
59
# modifying RED value
>>>img.itemset((10,10,2), 100)
>>>img.item(10,10,2)
100
訪問圖片屬性
圖片屬性包括行數(shù)丰歌,列數(shù),通道數(shù)屉凯,圖片數(shù)據(jù)類型动遭,像素?cái)?shù)等。
圖片的形狀可以通過img.shape獲得神得,它會放回一個(gè)包含行數(shù)厘惦,列數(shù)的通道數(shù)的元組(如果圖片是彩色的):
>>>print img.shape
(342, 548, 3)
注意:
如果圖片是灰度的,返回的元組只包含行數(shù)和列數(shù)哩簿。所以檢查是否加載的圖片是灰度的還是彩色的可以通過這個(gè)來做
所有的像素?cái)?shù)可以通過img.size來訪問:
>>>print img.size
562248
圖片數(shù)據(jù)類型可以通過img.dtype獲得:
>>>print img.dtype
uint8
注意:
img.dtype在調(diào)試的時(shí)候很重要宵蕉,因?yàn)榇罅縊penCV-Python代碼里的錯(cuò)誤都是有錯(cuò)誤的數(shù)據(jù)類型導(dǎo)致的。
圖片ROI
有時(shí)候节榜,你會需要處理圖片的特定區(qū)域羡玛。對于圖片的眼部識別,首先對整個(gè)圖片進(jìn)行面部識別宗苍,找到臉以后稼稿,在臉的區(qū)域內(nèi)找眼睛。這個(gè)方法能夠提高準(zhǔn)確度(因?yàn)檠劬偸窃谀樕系模篋)性能上也好(因?yàn)槲覀冋业膮^(qū)域更谢淇摺)
ROI是通過Numpy的索引來獲得的让歼,這里我們選擇球,然后把它復(fù)制到圖片的另一個(gè)區(qū)域:
>>>ball = img[280:340,330:390]
>>>img[273:333,100:160] = ball
分割和合并圖片
圖片的B, G, R通道可以被分割成他們各自的片丽啡,各個(gè)通道可以被合并成BGR圖片谋右。
>>>b,g,r = cv2.split(img)
>>>img=cv2.merge((b,g,r))
或者
>>>b = img[:,:,0]
假設(shè)你想把所有的紅色像素變成0,你不用這么分割补箍,你可以簡單的使用Numpy索引改执,這樣更快
>>>img[:,:,2]=0
警告:
cv2.split()是一個(gè)成本很高的操作(執(zhí)行時(shí)間),所以只在必要的時(shí)候使用坑雅。Numpy索引要更有效率辈挂,能用就用。
制作圖片的邊框
如果你想要在圖片周圍生成邊框裹粤,類似于相框终蒂,你可以使用cv2.copyMakeBorder()函數(shù)。但是它還能用于卷積蛹尝,0內(nèi)邊距等后豫。這個(gè)函數(shù)有下面這些參數(shù):
·src - 輸入圖片
·top, bottom, left, right - 各個(gè)方向的邊框像素寬度
·borderType - 標(biāo)志位悉尾,定義要加什么樣的邊框突那,可以是下列類型:
? ? ? ? ·cv2.BORDER_CONSTANT - 添加固定的彩色邊。值需要在后面的參數(shù)提供构眯。
? ? ? ? ·cv2.BORDER_REFLECT - 邊框是鏡像的愕难,像這樣:fedcba/abcdefgh/hgfedcb
? ? ? ? ·cv2.BORDER_REFLECT_101或cv2.BORDER_DEFAULT - 和上面一樣,但是有點(diǎn)變化,像這樣:gfedcb/abcdefgh/gfedcba
? ? ? ? ·cv2.BORDER_REPLICATE - 最后的元素是重復(fù)的猫缭,像這樣:aaaaaa/abcdefgh/hhhhhhh
? ? ? ? ·cv2.BORDER_WRAP - 沒法解釋葱弟,看上去是這樣: cdefgh/abcdefgh/abcdefg
·value - 如果邊的類型是cv2.BORDER_CONSTANT 這個(gè)值就是邊的顏色。
下面是個(gè)列子猜丹,展示了所有這些邊框的類型:
import cv2
import numpy as np
from matplotlib import pyplot as plt
BLUE = [255,0,0]
img1 = cv2.imread('opencv_logo.png')
replicate = cv2.copyMakeBorder(img1,10,10,10,10, cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_WRAP)
constant=cv2.copyMakeBorder(img1,10,10,10,10,cv2.BORDER_CONSTANT,value=BLUE)
plt.subplot(231),plt.imshow(img1,'gray'),plt.title('ORIGINAL')
plt.subplot(232),plt.imshow(replicate,'gray'),plt.title('REPLICATE')
plt.subplot(233),plt.imshow(reflect,'gray'),plt.title('REFLECT')
plt.subplot(234),plt.imshow(reflect101,'gray'),plt.title('REFLECT_101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')
plt.show()
END