使用 OpenCV 实现万花筒效果

发布于:2025-05-21 ⋅ 阅读:(14) ⋅ 点赞:(0)

万花筒效果(Kaleidoscope Effect)是一种图像处理效果,通过对图像进行对称旋转或镜像处理,产生具有多重反射和对称的艺术效果。它常用于视频编辑、视觉艺术、游戏设计等领域,为图像添加富有创意和视觉冲击力的效果。

在这篇文章中,我们将介绍如何使用 OpenCV 实现万花筒效果,通过截取一个图像扇形区域并进行旋转与镜像拼接,构建出万花筒的视觉效果。


1. 万花筒效果的原理

万花筒效果的基本原理是将一张图像分成多个对称的扇形部分,然后将这些扇形部分旋转和镜像拼接,最终形成一个完整的对称图案。我们可以按以下步骤操作:

  1. 获取图像中心点,作为对称的中心。

  2. 提取一个扇形区域,例如60°的扇形,确保图像的一部分是对称且有规律的。

  3. 旋转并镜像:通过旋转和镜像操作,将扇形区域重复多个次,形成完整的图像。

  4. 拼接成万花筒效果:将旋转后的扇形拼接起来,形成360°的圆形图案。


2. 使用 OpenCV 实现万花筒效果

步骤 1:导入必要的库

首先,我们需要导入 OpenCV 和 NumPy 库。OpenCV 用于图像处理,NumPy 用于数组操作。

import cv2 import numpy as np import math

步骤 2:实现 FrameObject 类

在我们的代码中,实现了一个 FrameObject 类,该类包含一个 do 方法,用于处理图像并生成万花筒效果,可迅速集成到PiscTrace。

步骤 3:图像处理步骤解析

  1. 创建掩膜:我们使用 cv2.fillConvexPoly 来创建一个 60° 的扇形掩膜。通过 math.radians(a) 将角度转换为弧度,然后计算出每个扇形点的坐标。

  2. 提取扇形区域:使用 cv2.bitwise_and 函数,从原图中提取出与掩膜重合的部分。

  3. 旋转与镜像:在循环中,我们通过 cv2.getRotationMatrix2D 生成旋转矩阵,并使用 cv2.warpAffine 执行旋转。同时,偶数段的扇形会使用 cv2.flip 函数进行水平翻转,以产生镜像效果。

  4. 拼接图像:通过 cv2.bitwise_or 将每次旋转后的扇形合并到输出图像中,最终形成完整的万花筒效果。

步骤 4:展示结果

最后,我们可以通过 OpenCV 显示图像来查看万花筒效果。

普通裁剪

import cv2
import numpy as np
import math

class FrameObject:
    def __init__(self):
        pass

    def do(self, frame, device=None):
        h, w = frame.shape[:2]
        center = (w // 2, h // 2)
        radius = min(center[0], center[1])

        # 创建空画布
        output = np.zeros_like(frame)

        # 扇形角度
        angle = 60
        num_segments = 360 // angle

        # 创建一个扇形掩膜(60度)
        mask = np.zeros((h, w), dtype=np.uint8)
        pts = [center]
        for a in range(0, angle + 1):
            rad = math.radians(a)
            x = int(center[0] + radius * math.cos(rad))
            y = int(center[1] - radius * math.sin(rad))
            pts.append((x, y))
        cv2.fillConvexPoly(mask, np.array(pts, dtype=np.int32), 255)

        # 提取原图中对应的扇形区域
        sector = cv2.bitwise_and(frame, frame, mask=mask)

        # 将扇形旋转并拼接
        for i in range(num_segments):
            M = cv2.getRotationMatrix2D(center, -i * angle, 1.0)
            rotated = cv2.warpAffine(sector, M, (w, h))
            output = cv2.bitwise_or(output, rotated)

        return output


3. 扩展与优化

  • 动态调整角度:通过修改 angle 的值,您可以控制每个扇形的大小,例如调整为 45° 或 30°,从而改变最终的图像效果。

  • 实时视频流:如果您希望在视频流中应用万花筒效果,可以通过 OpenCV 捕获视频帧并实时处理。可以结合 cv2.VideoCapturecv2.VideoWriter 来处理实时视频流并保存结果。

  • 颜色和光效:可以在每个扇形区域上应用颜色叠加、模糊、对比度增强等效果,使万花筒的视觉效果更为丰富。

镜像裁剪

import cv2
import numpy as np
import math

class FrameObject:
    def __init__(self):
        pass

    def do(self, frame, device=None):
        h, w = frame.shape[:2]
        center = (w // 2, h // 2)
        radius = min(center[0], center[1])

        angle = 60
        num_segments = 360 // angle

        # 1. 创建一个60°扇形掩膜
        mask = np.zeros((h, w), dtype=np.uint8)
        pts = [center]
        for a in range(0, angle + 1):
            rad = math.radians(a)
            x = int(center[0] + radius * math.cos(rad))
            y = int(center[1] - radius * math.sin(rad))
            pts.append((x, y))
        cv2.fillConvexPoly(mask, np.array(pts, dtype=np.int32), 255)

        # 2. 提取原图的扇形区域
        sector = cv2.bitwise_and(frame, frame, mask=mask)

        # 3. 初始化输出图像
        output = np.zeros_like(frame)

        # 4. 拼接镜像扇形片段
        for i in range(num_segments):
            rotated_sector = sector.copy()

            # 偶数片做水平翻转
            if i % 2 == 1:
                rotated_sector = cv2.flip(rotated_sector, 1)

            # 旋转到对应角度
            M = cv2.getRotationMatrix2D(center, -i * angle, 1.0)
            rotated = cv2.warpAffine(rotated_sector, M, (w, h))

            # 合并到输出图像
            output = cv2.bitwise_or(output, rotated)

        return output


4. 总结

本文介绍了如何使用 OpenCV 实现万花筒效果,通过图像旋转和镜像拼接,使图像呈现出对称而富有艺术感的效果。通过简单的图像处理技巧,您可以轻松创建出精美的视觉效果,并将其应用于艺术创作、动画制作等领域。


网站公告

今日签到

点亮在社区的每一天
去签到