当前位置: 首页 > news >正文

【OpenCV实现图像:使用OpenCV生成拼图效果】

文章目录

    • 概要
    • 通用配置
    • 不考虑间隔代码实现
    • 考虑间隔代码实现
    • 小结

概要

概要:

拼图效果是一种将图像切割为相邻正方形并重新排列的艺术效果。在生成拼图效果时,可以考虑不同的模式,包括是否考虑间隔和如何处理不能整除的部分。

不考虑间隔,忽略不能整除部分:
相邻正方形之间没有间隔,同时高度不能整除的部分直接被忽略。
示例图中展示了正方形紧密排列,没有任何间隔,不整除的部分被舍弃。
在这里插入图片描述

不考虑间隔,对不能整除部分进行空白填充:
相邻正方形之间没有间隔,同时对高度不能整除的部分进行白色填充。
示例图中呈现了正方形之间无缝连接,高度不能整除的部分填充为白色。
在这里插入图片描述

考虑间隔,忽略不能整除部分:
相邻正方形之间存在间隙,间隔距离为3像素,同时高度不能整除的部分直接被忽略。
示例图中显示了正方形之间的间隔,不整除的部分被舍弃。
在这里插入图片描述

考虑间隔,对不能整除部分进行空白填充:
相邻正方形之间存在间隙,间隔距离为3像素,同时对高度不能整除的部分进行白色填充。
示例图中演示了正方形之间的间隔,高度不能整除的部分填充为白色。
在这里插入图片描述

通用配置

为了统一上述代码,我们设置通用配置项如下:

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: 表示相邻正方形间间隔的大小

不考虑间隔代码实现

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)

完整代码:

import cv2
import numpy as np
import math

# 通用配置
config = {
    "cell_num": 7,
    "whether_crop_image_height": True,
    "whether_with_gap": False,
    "gap_width": 0
}

# 读取图像
img = cv2.imread("img.png")

# 获取每行格子数目和输入图像信息
w_count = config['cell_num']
src_height = img.shape[0]
src_width = img.shape[1]

# 计算每个格子的长度以及结果图像的宽度
sub_length = int(src_width / w_count)
new_width = sub_length * w_count

# 根据是否需要对高度进行空白填充,计算结果图像的高度
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

# 对结果图进行赋值
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, :]

# 画格子
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)

# 展示生成的拼图效果
cv2.imshow('Mosaic Effect', img_t)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
带填充的结果:

import cv2
import numpy as np
import math

# 通用配置
config = {
    "cell_num": 7,
    "whether_crop_image_height": True,
    "whether_with_gap": False,
    "gap_width": 0
}

# 读取图像
img = cv2.imread("img.png")

# 获取每行格子数目和输入图像信息
w_count = config['cell_num']
src_height = img.shape[0]
src_width = img.shape[1]

# 计算每个格子的长度、间隔长度以及结果图像的宽度
sub_length = int(src_width / w_count)
gap_length = int(config["gap_width"])
new_width = sub_length * w_count + gap_length * (w_count - 1)

# 根据是否需要对高度进行空白填充,计算结果图像的高度
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)

# 对结果图进行赋值
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, :]

# 展示生成的拼图效果
cv2.imshow('Mosaic Effect with Fill', img_t)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

不考虑间隔,带填充的情况:
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, :]
考虑间隔,带填充的情况:
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, :]

在带填充的情况下,会对不能整除的高度部分进行空白填充。带填充的拼图效果会更整齐,而不带填充的情况下可能会有一些截断。

考虑间隔代码实现

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, :]

全部代码

import cv2
import numpy as np
import math

# 通用配置
config = {
    "cell_num": 7,
    "whether_crop_image_height": True,
    "whether_with_gap": True,
    "gap_width": 3
}

# 读取图像
img = cv2.imread("img.png")

# 获取每行格子数目和输入图像信息
w_count = config['cell_num']
src_height = img.shape[0]
src_width = img.shape[1]

# 计算每个格子的长度、间隔长度以及结果图像的宽度
sub_length = int(src_width / w_count)
gap_length = int(config["gap_width"])
new_width = sub_length * w_count + gap_length * (w_count - 1)

# 根据是否需要对高度进行空白填充,计算结果图像的高度
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)

# 对结果图进行赋值
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, :]

# 绘制间隔
if config['whether_with_gap']:
    for i in range(h_count):
        for j in range(w_count - 1):
            begin_x = sub_length * (j + 1) + gap_length * j
            begin_y = sub_length * i + gap_length * i
            cv2.line(img_t, (begin_x, begin_y), (begin_x, begin_y + sub_length), color=(205, 205, 74), thickness=1)

# 展示生成的带填充和间隔的拼图效果
cv2.imshow('Mosaic Effect with Fill and Gap', img_t)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

小结

通过使用OpenCV库和Python编程语言,实现了图像拼图效果的生成。

拼图效果生成: 根据用户的需求,实现了两种不同的拼图效果生成方式。
一种是不考虑间隔,可以选择是否对高度不能整除的部分进行空白填充;另一种是考虑间隔,可以选择相邻正方形之间是否存在间隔,以及间隔的大小,同样可以选择是否对高度不能整除的部分进行空白填充。
通用配置: 引入了通用配置项,用户可以通过修改配置来调整拼图的格子数、是否裁剪高度、是否考虑间隔以及间隔的宽度等参数。
代码优化: 封装了一些功能函数,使代码更加模块化和可读性更强。

相关文章:

  • Springboot websocket前端无法访问到,Websocket因AOP代理 前端无法请求到
  • 五种多目标优化算法(MOJS、NSGA3、MOGWO、NSWOA、MOPSO)求解微电网多目标优化调度(MATLAB代码)
  • Tomcat实现WebSocket即时通讯 Java实现WebSocket的两种方式
  • GEE:梯度提升树(Gradient Boosting Tree)分类教程(样本制作、特征添加、训练、精度、参数优化、贡献度、统计面积)
  • letcode::数组中的第k个最大元素
  • 软件设计先进性之虚拟化技术的应用
  • 三、Keil安装芯片包、下载固件库、建立STM32工程模板
  • Ceres使用
  • 数据结构总复习
  • Github Copilot AI编码完成工具
  • 【限时免费】20天拿下华为OD笔试之【双指针】2023Q1A-两数之和绝对值最小【欧弟算法】全网注释最详细分类最全的华为OD真题题解
  • 逻辑回归
  • 激光塑料透光率检测仪进行材料质量监控
  • 【数据库篇】关系模式的表示——(1)问题的提出
  • 目标检测 详解SSD原理,数据处理与复现
  • SparkSession介绍
  • mysql 性能参数调优详解
  • 随便问问webtab的记录(1)
  • HTML网站稳定性状态监控平台源码
  • Log4j2.xml不生效:WARN StatusLogger Multiple logging implementations found:
  • 字母哥动了离开的心思,他和雄鹿队的缘分早就到了头
  • 江西省市场监管局原局长谢来发被双开:违规接受旅游活动安排
  • 甘肃:今年6月前,由县级党委、政府制定农村彩礼倡导性标准
  • 他站在当代思想的地平线上,眺望浪漫主义的余晖
  • 中国工程院院士、国医大师石学敏逝世
  • 数说母亲节|全球11亿女性进入更年期,“不是忍忍就好”