【計算機視覺處理三】圖像基本處理

圖像基本處理

一、圖像切片

在前面咱們瞭解到opencv中的圖像實際上就是一個ndarray數組,咱們對ndarray數組進行操做就是對圖像進行操做。咱們先來看一下切片查找,這是咱們很是經常使用的一個操做。python

(1)一維數組的切片

咱們來看看切片的語法,對於一維的數組咱們能夠經過下面的操做獲取第0個到第4個元素:數組

array[0:5]

從上面能夠知道咱們的切片操做是左閉右開的。上面的切片操做咱們能夠簡寫一下:ruby

array[:5]

若是咱們沒有設置第一個值,則表示從頭開始切片。固然咱們還能夠省略第二個值,這時含義就是取到最後一個元素,好比下面的操做:微信

array[3:]

咱們用一個實際的例子來看看切片操做:函數

import numpy as np# 建立一個一維的ndarray數組,數據爲[0, 1, 2, 3, 4, 5, 6, 7]array = np.array([0, 1, 2, 3, 4, 5, 6, 7])# 取0到4個元素print(array[0:5])print(array[:5])# 取第3個到最後一個元素print(array[3:])

輸出內容以下:flex

[0 1 2 3 4][0 1 2 3 4][3 4 5 6 7]

咱們能夠把切片操做總結爲:ui

# 左閉右開array[start: end-1]

當咱們以第0個開始,獲取以最後一個結尾的話,對應的值是能夠省略的。spa

(2)二維數組的切片

在圖像處理中,咱們更關注二維數組的切片。它的語法和一維數組很類似。爲了方便理解,咱們直接使用圖片來進行切片,好比下面這張圖片:.net

二維數組切片的語法以下:3d

array[start:end-1, start:end-1]

如今咱們須要明確一點,左邊部分是對高的截取,右邊部分是對寬的截取。那如今我要截取圖片的左半部分的操做應該以下:

import cv2# 讀取圖片img = cv2.imread('xyql.jpg')# 獲取圖片的寬,併除2width = img.shape[1]//2# 對圖片進行切片,截取左半部分left = img[:, :width]# 顯示圖像三步驟cv2.imshow('left', left)cv2.waitKey(0)cv2.destroyAllWindows()

其中切片的代碼是:

left = img[:, :width]

左邊的是截取高,咱們須要所有截取,所以兩個值均可以省略。右邊咱們只須要截取左半部分,所以左邊的值能夠省略,右邊的值則是咱們前面計算到的寬度。下面是效果圖:

這裏須要注意一點,彩色圖像實際上是三維的,可是咱們沒有操做第三個維度。

二、圖片區域替換

既然咱們知道如何切片,那咱們就能夠對指定區域進行替換。不過須要注意替換和被替換的區域形狀要相同,即shape屬性要同樣。好比我要把圖片左上角100*100的區域替換成白色,那我能夠進行以下操做:

import cv2import numpy as npimg = cv2.imread('1.jpg')# 建立一個100*100的白色圖像replace_img = np.ones((100, 100), dtype=np.uint8)*255# 將圖片左上角100*100區域替換img[:100, :100] = replace_img

運行後會發現報了以下錯誤:

 img[:100, :100] = replace_imgValueError: could not broadcast input array from shape (100,100) into shape (100,100,3)

它的意思是不能將(100, 100)的圖像轉換成(100, 100, 3)的圖像,也就是形狀不匹配。在替換時咱們須要特別注意這一點,咱們將上面的代碼進行一些修改:

import cv2import numpy as npimg = cv2.imread('xyql.jpg')replace_img = np.ones((100, 100, 3), dtype=np.uint8)*255img[:100, :100] = replace_img

*這樣咱們就能夠成功替換了,效果以下:

其實用上面的操做咱們能夠實現一個「雙胞胎」效果,下面咱們就來看看吧。

三、實現「雙胞胎」效果

咱們先準備兩張圖片,保證相機在沒有移動的狀況下拍兩張圖片,好比下面兩張:

這是我剛拍的兩張圖片,由於相機沒有移動,因此背景應該是同樣的。咱們能夠經過下面的代碼把兩個夢幻合併到一張圖片上:

import cv2# 讀取兩張圖片img1 = cv2.imread('mh1.JPG')img2 = cv2.imread('mh2.JPG')# 求出寬的中間值mid = img1.shape[1]//2# 把mh2的右半邊替換到mh1的右半部分img1[:, mid:] = img2[:, mid:]# 將拼接後的圖片保存到本地cv2.imwrite('result.jpg', img1)

上面代碼很是簡單,咱們只須要關注下面這句:

img1[:, mid:] = img2[:, mid:]

img1和img2的shape都是同樣的,截取的區域也是同樣的,因此進行替換沒有上面問題。最後咱們經過:

cv2.imwrite('result.jpg', img1)

對圖片進行保存。由於咱們是直接對img1進行操做,所以咱們直接保存img1就行了。下面是咱們的效果圖:


這裏須要多說一句,我只有一個夢幻。


四、numpy生成數組

在上一篇中咱們使用下面的代碼生成了一個數組:

im = np.zeros((3, 3, 1), dtype=np.uint8)

對於數組numpy來講咱們是生成一個數組,可是對opencv來講是生成一張圖片。下面咱們來看看numpy生成數組的一些操做。

(1)np.ones

咱們能夠經過numpy的ones函數生成一個元素全爲1的數組,好比下面的代碼:

np.ones((100, 100), dtype=np.uint8)

ones接收兩個參數,第一個參數是數組的shape,第二關則是數組元素的類型,其中np.uint8表示無符號的8位整型,即範圍在(0-255)之間。咱們能夠用opencv顯示一下上面的圖片:

import cv2import numpy as np# 生成一個100*100的圖片,每一個元素的值都爲1img = np.ones((100, 100), dtype=np.uint8)cv2.imwrite('result.jpg', img)

效果圖以下:

由於1很接近0,因此圖片的顏色接近於黑色。咱們能夠經過下面的操做對每一個元素進行操做:

import cv2import numpy as npimg = np.ones((100, 100), dtype=np.uint8) * 127cv2.imwrite('result.jpg', img)

咱們生成元素爲1的數組後,如何進行乘127的操做,這樣就能夠對每一個元素進行乘127操做。這時候數組的每一個元素都是127,下面是顯示效果:

固然咱們的圖片是二維的,對opencv來講是一個灰度圖。若是想要生成一個彩色圖像,咱們能夠生成一個三維的圖像,後續咱們會繼續講解。

(2)np.zeros

np.zeros和ones沒有上面區別,只是它元素的內容是0。咱們來簡單看一下:

import numpy as npimg = np.zeros((5, 5), dtype=np.uint8)print(img)

爲了方便看,咱們直接生成一個簡單的數組,輸出結果以下:

[[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]

其它的都再也不細說了。


本文分享自微信公衆號 - ZackSock(ZackSock)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索