最近寫論文遇到一個問題,就是我們使用python matplotlib.pyplot包中subplot創建兩個子圖,但是創建的子圖並不符合我們的預期需求,於是乎記錄下來其中的填坑指南。
1. 初始問題
假設我們現在我們有以下局部代碼,假設這裏的A,B是提前已知的np.array數組,A shape=(128, 128),B shape=(128, 6), 那麼我們想讓這兩個A,B拼接一起,然後一個很自然的考慮便是使用了subplot,最後保存爲C。
plt.figure(1)
plt.subplot(121)
plt.imshow(A, cmap='gray')
plt.xticks([])
plt.yticks([])
plt.subplot(122)
plt.imshow(B, cmap='gray')
plt.xticks([])
plt.yticks([])
plt.savefig(C, dpi=300)
但是結果竟然顯示爲這樣,一方面右側的圖像進行了拉伸,而且兩幅圖像間隔很大,並且四周有很多空白,這顯然不符合我們的預期。
2. 初步嘗試
首先我們搜了以下博客
然後簡單嘗試了一下,雖然可以一定程度上控制間距,但是右側拉伸的以及四周空白並沒有得到解決。
3. 嘗試
經過一番嘗試,覺得很麻煩,後面打算使用PS來p圖。正在這個時候,突然靈光一閃,爲什麼一定要使用subplot函數啊,有沒有其他拼接的方法了,於是乎我們的問題就從“如何讓subplot子圖之間更加緊湊”變成了“如何使用python拼接圖像”,然後便收到了意想不到的收穫。
3.1 前期工作
在說明解決方法之前,我們在需要解決一個問題,就是python如何保存圖像?雖然這個問題不難,但是不同的方法得到了結果也是不盡相同的,有些會導致圖像出現一些白邊,這裏的話我們需要保存的圖像是原始尺寸,沒有經過修飾的。即假如原始圖像是(128, 6)我們保存的圖像也是這麼大。這裏我們使用函數scipy.misc
保存圖像。參考的是python中將Numpy數組保存爲圖像
3.2 初步解決
我們無意間看到這樣一篇博客Python Image實現圖片橫向和縱向拼接然後直覺告訴我們這可能就是我們想要的,然後我們對代碼稍微進行了一點修改,讓它符合我們預期,代碼如下:
# -*- coding:utf-8 -*-
__author__ = 'ShawDa'
from PIL import Image
def join(png1, png2, spacing, save_position, flag='horizontal'):
"""
:param png1: png1 path
:param png2: png2 path
:param spacing: spacing width, default 0
:param save_position: save image
:param flag: horizontal or vertical
:return:
"""
img1, img2 = Image.open(png1), Image.open(png2)
size1, size2 = img1.size, img2.size
if flag == 'horizontal':
joint = Image.new('RGB', (size1[0]+size2[0] + spacing, size1[1]))
loc1, loc2 = (0, 0), (size1[0] + spacing, 0)
joint.paste(img1, loc1)
joint.paste(img2, loc2)
joint.save(save_position)
elif flag == 'vertical':
joint = Image.new('RGB', (size1[0], size1[1]+size2[1] + spacing))
loc1, loc2 = (0, 0), (0, size1[1] + spacing)
joint.paste(img1, loc1)
joint.paste(img2, loc2)
joint.save(save_position)
if __name__ == '__main__':
img1 = 'mask_4.tif'
img2 = 'mask_t4.tif'
join(img1, img2, 10, 'merge_4.tif')
# join(png, png, flag='vertical')
函數說明:
png1
和png2
分別是兩張圖片的位置spacing
控制着兩張圖片拼接的距離,即通過控制這個讓兩張圖像不至於靠的太近。save_position
文件保存位置flag
控制水平拼接還是垂直拼接,默認是水平拼接。
可以看出這個符合我們的預期效果。
3.3 進一步擴展
寫到這裏我們已經完成了預期的需求了,但是仔細想想如果說現在拼接的不是兩張圖,而是100張圖,比如是10×10的大圖,或者是20×5的大圖,顯然上述代碼無法完成需求,也就是擴展性不足,那麼我們如何遷移了?
經過一番網上搜索,發現已經有大神寫出來, 這裏就不造輪子了,這是搬運一下了,思路也是類似的。
1.基於python的多張不同寬高圖片拼接成大圖
2. 基於python的多張不同寬高圖片拼接成大圖——行自適應
有時候遇到問題換一個角度,可能就不那麼難了。