由于本人单位有项目正好用到了图像拼接的算法,因此怀着学习的态度进行了基于Opencv的SIFT特征(传统方法)进行图像拼接的尝试,单位的图片为非固定视角无人机航拍图,且图片数量较多,因此需要处理速度与精准度要求较高。虽进行了尝试,但效果不够理想(不理想的结果会在最后贴出)。
总体程序设计思路如下:
图片预处理-->图像特征点采集-->特征点匹配-->图像透视变换-->贴图-->图像后处理
由于每次的图片量有将近两千张左右,所以我将整个拼接程序分成了三级:
每一级拼接根据计算机的内存与cpu的处理运算能力进行手动设置张数与图片采集大小
第一篇文章先放一下图像预处理部分以及文件结构(代码如下):
文件目录结构如下:
stitching为项目主程序
程序运行效果图:
此图为拼接15张航拍图片效果(一级拼接效果)(非同一视角)
参数设置文件content.py:
"""
程序所有常参设置
"""
input_images_path = "./test_image" #图片读取路径
input_two_images_path = "./temp/one_filter" #一级合成拼接后的图片
input_three_images_path = "./temp/two_filter" #二级合成拼接后的图片
out_put_path = "./result" #三级合成输出结果地址
input_images_height = 1024 #设置每张图片resize后的大小(一级合成)
image_number = 15 #设置每次读取的图片数量
distance_factor = 0.7 #过滤匹配点对系数(初始系数,程序会根据点对数自行修改)
min_good_points = 150 #最小通过点对数(小于100组点对视为不合格,程序会自行调整参数,直至在最大最小值范围内)
max_good_points = 200 #最大通过点对数(大于200组点对同样视为不合格,程序会自行调整参数,直至在最大最小值范围内)
此函数用来设置拼接程序中的一些常量
输入图片预处理mosaic_input.py:
import image_stitching.content as content #常量函数
import cv2
class input_operation():
def __init__(self,images_name,flage,read_path):
"""
设置函数常参
"""
self.images_name = images_name
self.path = read_path
# 获取常参值
self.images = []
# 初始化图片列表
self.normal_images = self.images
# 获取降噪后的图片
self.image_name = []
self.input_ReadAll()
if flage == 1:
self.input_resize()
self.input_detail()
else:
self.images = self.normal_images
def input_ReadAll(self):
"""
读取列表下的所有图片文件并存在images中
"""
for i,image_name in enumerate(self.images_name):
#列表循环
print("读取图片:{}/{}".format(i + 1,len(self.images_name)))
image = cv2.imread("{}/{}".format(self.path, image_name))
#拼接地址
self.images.append(image)
#添加至列表中
def input_resize(self):
"""
重置传入图片大小
"""
for i,image in enumerate(self.images):
#获取图片在列表中的index和图片内容
print("正在进行图片缩放:{}/{}".format(i + 1,len(self.images)))
(image_width,image_height,_) = image.shape
#获取图片宽、高
ratio = image_width/image_height
#计算图片长宽比
new_height = content.input_images_height
#获取设置宽
resized_image = cv2.resize(image, (new_height,int(new_height*ratio)))
#计算高并且resize
self.images[i] = resized_image
#原位替换成处理后的图片
def input_detail(self):
"""
细节增强
"""
for i, image in enumerate(self.images):
print("正在进行图片细节增强:{}/{}".format(i + 1, len(self.images)))
detail_image = cv2.detailEnhance(image)
self.images[i] = detail_image
此函数主要用来预处理传入图片,主要是进行图片resize和进行图片细节增强,在后续的图片特征点匹配中以获取更多更精准的SIFT特征点,输入预处理到此结束。等我有时间的时候再继续写,希望大家点点赞。