利用 python 實現多張圖片的無損拼接

以下兩段是作者的心路歷程,圖個樂的可以看一看,想學乾貨可以直接略過。

就在昨天晚上,我要爲文章配圖,要求是將6張圖拼接爲3張圖。我就想,可以呀,PS應該很容易搞定,雖然我PS功底差,但架不住我有位朋友是 king of PS 呀(朋友間的調侃啦)。所以我將每張圖都剪切成一樣的高度,希望能對PS的過程有所幫助。
king of PS
好朋友不愧是 king of PS ,每張圖都拼接的很棒。但是,三張圖一一對比,細看還是有一些不太對齊,身患強迫症的我當然心中有些疙瘩。不過好朋友已經做的很棒了,我不能以自己的強迫症去強迫別人,所以我就走上了“自主研發”的道路。

導入 python 庫

import matplotlib.pyplot as plt
import skimage.io as io
import numpy as np

查看需要拼接的圖片

因爲工作需要,所以就不使用昨天晚上的圖片了。
我就拿了兩張截圖作爲示例演示。

首先看看拼接前的圖片是什麼樣子:

jzg = io.imread('jzg.jpg')   # np.ndarray, [h, w, c], 值域[0, 255], RGB
plt.imshow(jzg)   #查看圖片
plt.show()

解釋說明:“jzg”保存的是numpy的數組。

jzg

lgz = io.imread('lgz.jpg')   # np.ndarray, [h, w, c], 值域[0, 255], RGB
plt.imshow(lgz)
plt.show()

lgz
因爲我使用的是 jupyter Notebook,所以圖片顯示的不是太清晰。

查看一下圖片的大小和數組元素的數據類型。

print(jzg.shape)   #查看圖片的大小
print(jzg.dtype)   #查看數組元素數據類型
print(lgz.shape)
print(lgz.dtype)

輸出:

(720, 1280, 3)
uint8
(720, 1280, 3)
uint8

(720, 1280, 3)表示的是數組的大小,物理意義爲[h, w, c],分別是圖片的高度h,圖片的寬度w,圖片的通道數c。

可以看出兩者的大小完全一致,數組元素的數據類型爲“uint8”。

查看數組中元素的值域:

print([jzg.min(), jzg.max()])

輸出:

[0, 255]

橫向拼接

創建拼接用的數組:

pj1 = np.zeros((720,1280 + 1280,3))   #橫着拼接
pj1[:,:1280,:] = jzg.copy()   #圖片jzg在左
pj1[:,1280:,:] = lgz.copy()   #圖片lgz在右
print(pj1.dtype)   #查看數組元素類型

輸出:

float64

可以看出拼接後的數據類型不一樣了,所以要改一下,不然顯示的就是錯誤的。

pj1=np.array(pj1,dtype=np.uint8)   #將pj1數組元素數據類型的改爲"uint8"
plt.imshow(pj1)   #查看拼接情況
plt.show()

拼接後的圖片

保存拼接後的圖片

將拼接後的圖片保存在當前目錄下,也可以改爲其它的路徑。

io.imsave('pj1.jpg', pj1)   #保存拼接後的圖片

總結

橫向拼接的代碼總結如下:

import matplotlib.pyplot as plt
import skimage.io as io
import numpy as np

jzg = io.imread('jzg.jpg')   # np.ndarray, [h, w, c], 值域(0, 255), RGB
plt.imshow(jzg)   #查看圖片
plt.show()

lgz = io.imread('lgz.jpg')   # np.ndarray, [h, w, c], 值域(0, 255), RGB
plt.imshow(lgz)
plt.show()

print(jzg.shape)   #查看圖片的大小
print(jzg.dtype)   #查看數組元素數據類型
print(lgz.shape)
print(lgz.dtype)

pj1 = np.zeros((720,1280 + 1280,3))   #橫向拼接
pj1[:,:1280,:] = jzg.copy()   #圖片jzg在左
pj1[:,1280:,:] = lgz.copy()   #圖片lgz在右
print(pj1.dtype)   #查看數組元素類型

pj1=np.array(pj1,dtype=np.uint8)   #將pj1數組元素數據類型的改爲"uint8"

plt.imshow(pj1)   #查看拼接情況
plt.show()

io.imsave('pj1.jpg', pj1)   #保存拼接後的圖片

縱向拼接

當然,可以橫向拼接自然也可以縱向拼接,只需將拼接用的數組改爲如下:

pj2 = np.zeros((720 + 720,1280,3))   #橫向拼接

將拼接操作改爲:

pj1[:720,:,:] = jzg.copy()   #圖片jzg在上
pj1[720:,:,:] = lgz.copy()   #圖片lgz在下

然後其他步驟都一樣。

圖片間距

有些時候要求要有縫拼接,這時候就將拼接用的數組橫向或縱向變大,空白區域使用“0”或者“255”填充(我不知道“0”和“255”中,哪個代表白色,哪個代表黑色,需要的就自己去實驗或者查詢一下)。

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