opencv-python學習筆記(二)

圖像基本操作

. 當讀取完一個圖像之後,可以直接通過橫縱座標來返回該像素點的rgb值:

img = cv2.imread('kkxj.jpg')
px = img[100,100]
print(px)
#還可以通過第三個值選擇只打印某個通道的值
blue = img[100,100,0]
print(blue)
#還可以直接更改像素點的值
img[100,100] = [0,0,0]
print(img[100,100])
#以上方法可以通過函數item()和itemset()實現,但是都只能獲取或設置單通道的值
print(img.item(100,100,1))
img.itemset((100,100,2),100)
#顯示圖片信息(行,列,通道數(如果是彩色的話))
print(img.shape)
#打印像素點個數
print(img.size)
#打印圖像數據類型
print(img.dtype)
#選取部分圖像,前者時縱向長度,後者時橫向長度
ball = img[100:150,200:230]
#區域賦值
img[100:110,100:150] = ball
#圖像的bgr通道可以分開獲得
b,g,r = cv2.split(img)     
b = img[:,:,0]			#推薦
#也能合併起來組成圖像
img = cv2.merge((b,g,r))

爲圖像設置邊框

. 可以使用cv2.copyMakeBorder() 來爲圖像添加邊框,這個函數還在卷積運算,零填充等方面有更多應用。函數包含7個參數第一個是輸入的圖像,接着的四個分別是上下左右四個邊框的像素寬度,第六個參數是邊框類型標誌,它的值決定最後一個參數是否需要給出,其值如下:

類型 描述
cv2.BORDER_CONSTANT 添加恆定的彩色邊框,需要指定最後一個參數(邊框顏色)
cv2.BORDER_REFLECT 邊框將邊框元素進行鏡面反射,比如fedcba|abcdefgh|hgfedcb,中間被兩邊做鏡像反射
cv2.BORDER_REFLECT_101 (cv2.BORDER_DEFAULT) 與上訴類似,不過會拋棄末尾的值,比如fedcb|abcdefgh|gfedcb
cv2.BORDER_REPLICATE 末尾的值被複制,比如aaaaaa|abcdefgh|hhhhhh
cv2.BORDER_WRAP 無法解釋(???)
img = cv2.imread('kkxj.jpg')
#加藍色框
constant = cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_CONSTANT,value = [255,255,0])
cv2.imshow('f',constant)
cv2.waitKey(0)
cv2.destroyAllWindows()

圖像上的算術運算

覆蓋

. 圖像的加法可以使用opencv帶的函數cv2.add() 或是使用numpy操作,兩張圖片應該具有相同的深度和類型,或是其中一張都是標量值。不過add方法和unmpy操作的結果會有所不同:

x = np.uint8([250])
y = np.uint8([10])

print cv2.add(x,y)     		# 250+10 = 260 => 255
print x+y                  	# 250+10 = 260 % 256 = 4

. 前者得出的值是[[255]],後者得到的是取模運算後的值[4]。

圖像融合

. 這也是圖像的加法,不過是帶權的,這樣就給人一種融合的感覺,使用cv2.addWeighted() 給兩張圖像分配權重(0-1):

img1 = cv2.imread('img1.png')
img2 = cv2.imread('img2.jpg')

dst = cv2.addWeighted(img1,0.7,img2,0.3,0)

cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()  

位運算

. 位運算在做提取圖像的某些區域的操作的時候會很有用,如果直接使用add,會改變圖象的色彩,如果使用融合,會讓圖像變得有透明感,並且提取的區域可以不受形狀限制。

img1 = cv2.imread('kkxj.jpg')
img2 = cv2.imread('fire.png')

#將img2放在左上角
row,col,channel = img2.shape
roi = img1[0:row,0:col]

img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY) #灰度化
#二值化,第二個參數是閾值,cv2.THRESH_BINARY表示原圖像像素點的值大於閾值就置爲第三個參數的值
ret,mask = cv2.threshold(img2gray,10,255,cv2.THRESH_BINARY)
#像素點按位取反
mask_inv = cv2.bitwise_not(mask)

#第一個參數和第二個參數相同,就相當於和第三個參數的圖片做按位與操作,
#這裏相當於摳了個黑色凹槽
img1_bg = cv2.bitwise_and(roi,roi,mask = mask_inv)
#相當於摳出來的插件
img2_fg = cv2.bitwise_and(img2,img2,mask = mask)

#將插件插入插槽
dst = cv2.add(img1_bg,img2_fg)
#覆蓋原圖像的部分區域
img1[0:row,0:col] = dst

cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

性能測試與提高

衡量性能

. cv2.getTickCount函數返回指定的事件(比如開機)後到調用該函數經過的時間週期數,因此可以通過在某個函數開始前和結束後調用getTickCount函數獲得這個函數的執行時間。
. cv2.getTickFrequency函數返回時鐘週期的頻率,因此可以通過以下方式獲得函數執行時間:

e1 = cv2.getTickCount()
...
e2 = cv2.getTickCount()
time = (e2 - e1)/ cv2.getTickFrequency()

Opencv的默認優化功能

. 很多opencv函數都使用SSE2、AVX等指令集來實現優化,所以當系統支持這些功能的時候,應該加以使用,當然,opencv也是包含沒有使用優化的代碼的,因此,如果opencv啓用優化功能,將在運行的時候使用優化代碼,否則使用未優化代碼。
. 可以使用cv2.useOptimized() 函數來檢查是否啓用了優化功能,使用cv2.setUseOptimized() 函數來手動啓用或是禁用優化功能。使用與不使用通常會有明顯的性能區別。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章