【OpenCV学习笔记10】- 【彩蛋】使用cv.addWeighted()函数利用多张图片实现平滑过渡的幻灯片效果

发布时间:2024年01月12日

这是对于 OpenCV 官方文档的 核心操作的学习笔记。学习笔记中会记录官方给出的例子,也会给出自己根据官方的例子完成的更改代码,同样彩蛋的实现也会结合多个知识点一起实现一些小功能,来帮助我们对学会的知识点进行结合应用。
如果有喜欢我笔记的请麻烦帮我关注、点赞、评论。谢谢诸位。

学习笔记:
学习笔记目录里面会收录我关于OpenCV系列学习笔记博文,大家如果有什么不懂的可以通过阅读我的学习笔记进行学习。
【OpenCV学习笔记】- 学习笔记目录

彩蛋内容

使用cv.addWeighted()函数在文件夹中创建图像之间平滑过渡的幻灯片并放映。

实际是使用cv.addWeighted()函数利用多张图片实现平滑过渡的幻灯片效果。
直接上彩蛋代码
示例代码:

# 使用cv.addWeighted()函数在文件夹中创建图像之间平滑过渡的幻灯片并放映。
import cv2
import os


# 确保所有图像都被调整为同样的尺寸
def resize_images(image1, image2, target_size):
    height, width = target_size
    img1_resized = cv2.resize(image1, (width, height), interpolation=cv2.INTER_AREA)
    img2_resized = cv2.resize(image2, (width, height), interpolation=cv2.INTER_AREA)
    return img1_resized, img2_resized


# 设置过渡时间(秒)
transition_duration = 3

frame_rate = 10

# 指定图片文件夹路径
image_folder = '.../images/'

# 获取文件夹中所有图片文件名列表
images = sorted([f for f in os.listdir(image_folder) if f.endswith(('.jpg', '.png'))])

# 图像过渡步数(根据过渡时间和帧率估算)
frame_count_per_transition = transition_duration * frame_rate  # 假设每秒30帧
total_frame_count = (len(images) - 1) * frame_count_per_transition
# 这里的5是为了让我们权重的递进速度加快,大家可以自己按照需求调整
alpha_increment = 1.0 / (total_frame_count / 5)


current_num = 0
next_num = 1
# 记录步数
step_num = 0
current_image = None
next_image = None
# 循环遍历图片并添加平滑过渡效果
for i in range(total_frame_count):
    if current_image is None and next_image is None:
        current_image = cv2.imread(os.path.join(image_folder, images[current_num]))
        # 初始化输出图像大小和变量
        output_height, output_width = cv2.imread(os.path.join(image_folder, images[0])).shape[:2]
        # 设置目标尺寸
        # 假设已经确定了一个合适的输出尺寸
        target_size = (output_height, output_width)
        # 显示当前混合图像
        cv2.imshow('Slideshow with Transition', current_image)

    key = cv2.waitKey(1) & 0xFF
    # 如果达到最后一步或者用户按下'q'键退出
    if i == total_frame_count - 1 or key == ord('q'):
        break

    # 当过渡完成时,更新当前图像为下一个图像
    # 并且需要重制步数,如果不重制步数,会导致加载图片权重为负,图片加载取反
    this_image_index = i // frame_count_per_transition
    if current_num < len(images) and current_num < this_image_index:
        current_image = next_image
        next_image = None
        current_num += 1
        step_num = 0
	
	# 下一张图片在本张图片的1/12的帧数开始加载
    next_image_index = (next_num - 1) * frame_count_per_transition + frame_count_per_transition / 12
    if next_num < len(images) and i > next_image_index and (next_num - 1) == current_num:
        next_num += 1
        if next_num >= len(images):
            continue
        image_path = os.path.join(image_folder, images[next_num])
        print(image_path)
        next_image = cv2.imread(image_path)

	# 对下一张图片处理做判断
    if next_image is None:
        # 显示当前图像
        cv2.imshow('Slideshow with Transition', current_image)
        continue

    # 重新设置两张图片的尺寸
    current_image, next_image = resize_images(current_image, next_image, target_size)

    # 计算权重
    alpha = alpha_increment * (step_num + 1)
    print("alpha: " + str(alpha))
    beta = 1.0 - alpha
    print("beta: " + str(beta))
    # 混合图像
    blended_img = cv2.addWeighted(current_image, beta, next_image, alpha, 0)

    # 显示当前混合图像
    cv2.imshow('Slideshow with Transition', blended_img)
    step_num += 1

# 关闭显示窗口
cv2.destroyAllWindows()

没有想到一个彩蛋浪费了我不少时间去调试,调试过程中出现的问题有这些:

  1. 下一张图片的加载时机:这个很重要,如果加载时机不好,会让过渡变得很突兀;
  2. 权重的递进速度控制:如果你的递进速度过快会导致第二张图显示速度过快;如果你的递进速度过慢,会导致过度效果有卡顿;
  3. 重置步数:如果步数不重制,你会发现,加载到后面的图片,权重都为负数,展示的图片会取反,图片画面过暗;
  4. 重置第二张图:如果不重制,会导致过度效果之后画面重叠现象出现。

大家可以先尝试自己去实现这个彩蛋,我的实现仅供参考,当然我的实现并不是最优解,如果指正之处,可以留言。

文章来源:https://blog.csdn.net/q664243624/article/details/135559328
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。