python實現圖像拼接

最近寫論文遇到一個問題,就是我們使用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. 初步嘗試

       首先我們搜了以下博客

  1. matlab控制圖像的邊界(margin),subplot的間距(gap)
  2. python如何調整subplot的間距

然後簡單嘗試了一下,雖然可以一定程度上控制間距,但是右側拉伸的以及四周空白並沒有得到解決。

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')

函數說明:

  1. png1png2分別是兩張圖片的位置
  2. spacing控制着兩張圖片拼接的距離,即通過控制這個讓兩張圖像不至於靠的太近。
  3. save_position 文件保存位置
  4. flag控制水平拼接還是垂直拼接,默認是水平拼接。

在這裏插入圖片描述
可以看出這個符合我們的預期效果。

3.3 進一步擴展

寫到這裏我們已經完成了預期的需求了,但是仔細想想如果說現在拼接的不是兩張圖,而是100張圖,比如是10×10的大圖,或者是20×5的大圖,顯然上述代碼無法完成需求,也就是擴展性不足,那麼我們如何遷移了?

經過一番網上搜索,發現已經有大神寫出來, 這裏就不造輪子了,這是搬運一下了,思路也是類似的。

1.基於python的多張不同寬高圖片拼接成大圖
2. 基於python的多張不同寬高圖片拼接成大圖——行自適應

有時候遇到問題換一個角度,可能就不那麼難了。

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