1. 程式人生 > >圖片的裁剪和合並(python+opencv)

圖片的裁剪和合並(python+opencv)

遙感影像的裁剪和合並(python+opencv)

一、需求:

1)把一張解析度為13400*9333的遙感影像(RGB+alpha4個通道)裁剪成1024*1024的影像,用於作為深度學習神經網路的訓練集。 2)並且能夠把網路輸出結果的小圖片合併成原來的大小。 注:以上均捨棄不夠整除的部分

二:裁剪思路:

1、先匯入用到的庫 2、呼叫cv2.imread()讀取要裁剪的原始影像

imread()函式: 讀入圖片,共兩個引數,第一個引數為要讀入的圖片檔名,第二個引數為如何讀取圖片,包括cv2.IMREAD_COLOR:讀入一副彩色圖片;cv2.IMREAD_GRAYSCALE

:以灰度模式讀入圖片;cv2.IMREAD_UNCHANGED:讀入一幅圖片,幷包括其alpha通道。也可分別用1,0,-1代替,預設為1。

3、迴圈讀取原始影像,每隔rows行、cols列就儲存成一張圖片,並格式化儲存地址

裁剪程式碼如下:

"""
輸入:圖片路徑(path+filename),裁剪獲得小圖片的列數、行數(也即寬、高)
輸出:無
"""
def crop_one_picture(path,filename,cols,rows):
    img=cv2.imread(path+filename,-1)##讀取彩色影象,影象的透明度(alpha通道)被忽略,預設引數;灰度影象;讀取原始影象,包括alpha通道;可以用1,0,-1來表示
sum_rows=img.shape[0] #高度 sum_cols=img.shape[1] #寬度 save_path=path+"\\crop{0}_{1}\\".format(cols,rows) #儲存的路徑 if not os.path.exists(save_path): os.makedirs(save_path) print("裁剪所得{0}列圖片,{1}行圖片.".format(int(sum_cols/cols),int(sum_rows/rows))) for i in range(int(sum_cols/cols)): for
j in range(int(sum_rows/rows)): cv2.imwrite(save_path+os.path.splitext(filename)[0]+'_'+str(j)+'_'+str(i)+os.path.splitext(filename)[1],img[j*rows:(j+1)*rows,i*cols:(i+1)*cols,:]) #print(path+"\crop\\"+os.path.splitext(filename)[0]+'_'+str(j)+'_'+str(i)+os.path.splitext(filename)[1]) print("裁剪完成,得到{0}張圖片.".format(int(sum_cols/cols)*int(sum_rows/rows))) print("檔案儲存在{0}".format(save_path))

三:合併思路:

1、用file_name(root_path,picturetype)函式遍歷傳入的資料夾,得到所有符合格式的圖片路徑。root_path為資料夾路徑,picturetype為圖片字尾名:如”.tif”,”.jpg”

"""遍歷資料夾下某格式圖片"""
def file_name(root_path,picturetype):
    filename=[]
    for root,dirs,files in os.walk(root_path):
        for file in files:
            if os.path.splitext(file)[1]==picturetype:
                filename.append(os.path.join(root,file))
    return filename

2、按照裁剪所得的小圖片的檔名隱含的行列數找到它應該在的位置 3、儲存為merge.tif 合併程式碼如下:

"""

輸入:圖片路徑(path+filename),裁剪所的圖片的列的數量、行的數量
輸出:無
"""
def merge_picture(merge_path,num_of_cols,num_of_rows):
    filename=file_name(merge_path,".tif")
    shape=cv2.imread(filename[0]).shape    #三通道的影像需把-1改成1
    cols=shape[1]
    rows=shape[0]
    channels=shape[2]
    dst=np.zeros((rows*num_of_rows,cols*num_of_cols,channels),np.uint8)
    for i in range(len(filename)):
        img=cv2.imread(filename[i],-1)
        cols_th=int(filename[i].split("_")[-1].split('.')[0])
        rows_th=int(filename[i].split("_")[-2])
        roi=img[0:rows,0:cols,:]
        dst[rows_th*rows:(rows_th+1)*rows,cols_th*cols:(cols_th+1)*cols,:]=roi
    cv2.imwrite(merge_path+"merge.tif",dst)

三:呼叫函式示例及截圖:

一:呼叫裁剪函式示例

path='.\\input\\origin\\test\\'   #要裁剪的圖片所在的資料夾
filename='2015_rgbn.tif'    #要裁剪的圖片名
cols=1024        #小圖片的寬度(列數)
rows=1024        #小圖片的高度(行數)
crop_one_picture(path,filename,1024,1024)

原始圖片如下: 這裡寫圖片描述

得到結果截圖: 這裡寫圖片描述

二:呼叫合併圖片函式示例

merge_path=".\\input\\origin\\test\\crop1024_1024\\"   #要合併的小圖片所在的資料夾
num_of_cols=13    #列數
num_of_rows=9     #行數
merge_picture(merge_path,num_of_cols,num_of_rows)

得到的合併圖: 這裡寫圖片描述

上述所有程式碼已上傳到github