遥感影像的裁剪和合并(python+opencv)
一、需求:
1)把一张分辨率为134009333的遥感影像(RGB+alpha4个通道)裁剪成10241024的影像,用于作为深度学习神经网络的训练集。
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],-1).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