1 引言
最近无意中看到有同学对图像进行分割后,形成拼图效果,如下图所示:
猛然一看,感觉很酷炫有木有.既然我们是专门搞图像的,那我们就来研究下如何使用Python-Opencv来实现上述效果吧.
2 分析
上述问题,主要目的就是将图像切成一块一块的正方形,考虑相邻正方形之间是否留有空白,以及是否对不能整除的图像进行空白填充,我们可以得到四种切分方式.
2.1 不考虑间隔,忽略不能整除部分
这种模式下,相邻正方形之间没有间隔,同时高度不能整除的部分直接被忽略掉.
2.2 不考虑间隔,对不能整除部分进行空白填充
这种模式下,相邻正方形之间没有间隔,同时对高度不能整除的部分进行白色填充.样例图如下:
2.3 考虑间隔,忽略不能整除部分
这种模式下,相邻正方形之间存在间隙,间隔距离为3pixel,同时高度不能整除的部分直接被忽略掉.
2.4 考虑间隔,对不能整除部分进行空白填充
这种模式下,相邻正方形之间存在间隙,间隔距离为3pixel,同时对高度不能整除的部分进行白色填充.样例图如下:
3 代码实现
3.1 通用配置
为了统一上述代码,我们设置通用配置项如下:
config = {
"cell_num":7,
"whether_crop_image_height": True,
"whether_with_gap": True,
"gap_width":3
}
上述配置中,各项含义如下:
- cell_num: 表示每行划分格子个数
- whether_crop_image_height: 表示是否对高度不能整除部分进行空白填充
- whether_with_gap: 表示相邻正方形之间是否存在间隔
- gap_width: 表示相邻正方形间间隔的大小
3.2 不考虑间隔实现
1).获取每行格子数目和输入图像信息:
w_count = config['cell_num']
src_height = img.shape[0]
src_width = img.shape[1]
2).计算每个格子的长度以及结果图像的宽度
sub_length = int(src_width / w_count)
new_width = sub_length * w_count
3).根据是否需要对高度进行空白填充,计算结果图像的高度
if config['whether_crop_image_height']:
h_count = int(src_height / sub_length)
else:
h_count = math.ceil(src_height / sub_length)
new_height = sub_length * h_count
4).对结果图进行赋值
img_t = np.zeros(shape=(new_height,new_width,3),dtype=np.uint8) + 255
if config['whether_crop_image_height']:
img_t = img[:new_height,:new_width,:]
else:
img_t[:src_height, :new_width, :] = img[:src_height, :new_width, :]
5).画格子
for x_i in range(1, w_count):
cv2.line(img_t,(x_i*sub_length,0),(x_i*sub_length,new_height-1),color=(205,205,74),thickness=1)
for y_i in range(1, h_count):
cv2.line(img_t,(0,y_i*sub_length),(new_width-1,y_i*sub_length), color=(205,205,74), thickness=1)
不带填充的结果如下:
带填充的结果如下:
3.3 考虑间隔实现
1).获取每行格子数目和输入图像信息:
w_count = config['cell_num']
src_height = img.shape[0]
src_width = img.shape[1]
2).计算每个格子的长度,间隔长度以及结果图像的宽度
sub_length = int(src_width / w_count)
gap_length = int(config["gap_width"])
new_width = sub_length * w_count + gap_length * (w_count -1)
3).根据是否需要对高度进行空白填充,计算结果图像的高度
if config['whether_crop_image_height']:
h_count = int( (src_height + gap_length) / (sub_length+gap_length))
else:
h_count = math.ceil((src_height + gap_length) / (sub_length+gap_length))
new_height = sub_length * h_count + gap_length * (h_count-1)
4).对结果图进行赋值
img_t = np.zeros(shape=(new_height,new_width,3),dtype=np.uint8) + 255
if config['whether_crop_image_height']:
for i in range(h_count):
for j in range(w_count):
begin_x = sub_length * j
begin_y = sub_length * i
src_x = gap_length * j + begin_x
src_y = gap_length * i + begin_y
img_t[src_y:src_y+sub_length,src_x:src_x + sub_length,:] = img[begin_y:begin_y + sub_length,begin_x:begin_x + sub_length, :]
else:
for i in range(h_count):
for j in range(w_count):
begin_x = sub_length * j
begin_y = sub_length * i
src_x = gap_length * j + begin_x
src_y = gap_length * i + begin_y
if i<h_count-1:
img_t[src_y:src_y+sub_length,src_x:src_x + sub_length,:] = img[begin_y:begin_y + sub_length,begin_x:begin_x + sub_length, :]
else:
diff_height = src_height - sub_length * (h_count-1)
img_t[src_y:src_y + diff_height, src_x:src_x + sub_length, :] = img[begin_y:begin_y + diff_height,begin_x:begin_x + sub_length, :]
不带填充的结果如下:
带填充的结果如下:
4 总结
本文介绍了利用Python生成图像拼接效果的原理和相应的代码实现,并给出了完整的代码供参考学习.
您学废了吗?
5. 参考
关注公众号《AI算法之道》,获取更多AI算法资讯。
注: 完整代码,关注公众号,后台回复 cut_pic , 即可获取。