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

使用 OpenCV 实现“随机镜面墙”——多镜片密铺的哈哈镜效果

1. 引言

“哈哈镜”是一种典型的图像变形效果,通过局部镜面反射产生扭曲的视觉趣味。在计算机视觉和图像处理领域,这类效果不仅有趣,还能用于艺术创作、交互装置、视觉特效等场景。

传统的“哈哈镜”往往是针对整张图像做某种镜像或扭曲变换,而如果我们将图像划分为多个小镜片,每个镜片独立做镜面反射,拼成一面“镜子墙”,效果更丰富,也更具创意。

本文将介绍如何使用 Python 和 OpenCV 实现这样一种“随机镜面墙”效果:

  • 在图像上随机生成多个点,利用三角剖分将图像切成多个小三角形面片(镜片)。

  • 对每个镜片分别以其重心为中心做局部镜面反射变换。

  • 最后将所有变换后的镜片无缝拼接,形成一幅由多个镜面组成的“哈哈镜”墙。


2. 基础准备:OpenCV 简介

OpenCV 是一个开源的计算机视觉库,提供了丰富的图像处理功能,如图像读取、变换、绘制等。

本案例中,主要用到的功能包括:

  • cv2.fillConvexPoly:绘制多边形掩码

  • cv2.boundingRect:获取多边形的最小外接矩形

  • cv2.warpAffine:仿射变换实现局部镜像

  • NumPy 进行数组和坐标操作


3. 设计思路

3.1 随机采样点 + 边界点

在图像区域内随机采样若干点(50~100个),并额外加入图像四个角点,确保后续切割覆盖整幅图。

3.2 Delaunay 三角剖分密铺

使用 SciPy 的 Delaunay 对采样点做三角剖分,得到一组不重叠的三角形面片,组成密铺。

3.3 计算三角形重心

对每个三角形顶点坐标求均值,得到重心作为局部镜面的“反射中心”。

3.4 局部镜面反射变换

以三角形重心为中心,利用仿射变换矩阵实现水平或垂直镜像(或旋转+镜像)。

  • 例如水平镜像矩阵为:

M=[−102cx010]M = \begin{bmatrix} -1 & 0 & 2c_x \\ 0 & 1 & 0 \end{bmatrix}M=[−10​01​2cx​0​]

其中 cxc_xcx​ 是重心的水平坐标(相对于当前ROI局部坐标)。

3.5 裁剪与拼接

  • 对每个三角形计算外接矩形,裁剪图像和掩码。

  • 将镜像变换后的结果放回对应位置,只覆盖三角形区域。


4. 关键代码示例

import cv2
import numpy as np
from scipy.spatial import Delaunayclass FrameObject:def __init__(self):passdef do(self, frame, device):h, w = frame.shape[:2]# 生成随机点 + 添加四角num_points = np.random.randint(50, 101)points = np.random.randint(0, [w, h], size=(num_points, 2))corners = np.array([[0,0], [w-1,0], [w-1,h-1], [0,h-1]])points = np.vstack((points, corners))# Delaunay 三角剖分tri = Delaunay(points)triangles = points[tri.simplices]result = np.zeros_like(frame)for tri_pts in triangles:# 创建掩码,绘制三角形mask = np.zeros((h, w), dtype=np.uint8)cv2.fillConvexPoly(mask, tri_pts, 255)# 计算重心centroid = np.mean(tri_pts, axis=0)# 裁剪ROI区域x, y, bw, bh = cv2.boundingRect(tri_pts)roi = frame[y:y+bh, x:x+bw]mask_roi = mask[y:y+bh, x:x+bw]# 转换重心到ROI局部坐标系cx, cy = centroid - np.array([x, y])# 构造水平镜像仿射矩阵M = np.array([[-1, 0, 2*cx],[0, 1, 0]], dtype=np.float32)# 对ROI做镜像变换warped = cv2.warpAffine(roi, M, (bw, bh), flags=cv2.INTER_LINEAR)# 利用掩码覆盖变换结果mask_bin = (mask_roi > 0)for c in range(frame.shape[2]):result[y:y+bh, x:x+bw, c][mask_bin] = warped[:, :, c][mask_bin]return result

5. 运行效果与拓展

  • 运行后你会看到画面被切割成许多小三角形镜片,每个镜片都经过水平镜像,组成丰富的镜面墙效果。

  • 可以将 M 变换矩阵换成垂直镜像、旋转镜像,甚至结合水波扭曲,做出更多变化。

  • 采样点数越多,镜片越细密,视觉越复杂。


6. 总结

本文介绍了如何结合 OpenCV 和 SciPy,基于随机采样点和 Delaunay 三角剖分,将图像划分为多个小镜片,并对每个镜片独立应用镜像变换,模拟“镜子墙”哈哈镜效果。

此方法不仅简单高效,还极具扩展性。你可以基于此框架增加更多变换模式、动态动画或实时视频处理,创造更多炫酷的视觉效果。


如果你喜欢这篇教程,欢迎点赞、收藏和留言交流!
更多图像处理技术,欢迎关注我的博客。

http://www.lryc.cn/news/2386652.html

相关文章:

  • 鸿蒙仓颉开发语言实战教程:页面跳转和传参
  • 如何在Vue中实现延迟刷新列表:以Element UI的el-switch为例
  • 最新Spring Security实战教程(十六)微服务间安全通信 - JWT令牌传递与校验机制
  • MDM在智能健身设备管理中的技术应用分析
  • OSPF ABR汇总路由
  • 【五】Spring Cloud微服务开发:解决版本冲突全攻略
  • Spring Boot微服务架构(二):开发调试常见中文问题
  • Linux基础IO----动态库与静态库
  • LeetCode百题刷004(哈希表优化两数和问题)
  • 解析Java String.getBytes()编码与new String()解码的字符集转换机制
  • 从万有引力到深度学习,认识模型思维
  • 2022 年 9 月青少年软编等考 C 语言八级真题解析
  • FPGA通信之VGA与HDMI
  • Leetcode百题斩-二叉树
  • 修改 K8S Service 资源类型 NodePort 的端口范围
  • ACM Latex模板:合并添加作者和单位
  • 爬虫IP代理技术深度解析:场景、选型与实战应用
  • 将MCP(ModelContextProtocol)与Semantic Kernel集成(调用github)
  • 游戏引擎学习第311天:支持手动排序
  • LambdaQueryWrapper、MybatisPlus提供的基本接口方法、增删改查常用的接口方法、自定义 SQL
  • 深度学习---可视化
  • 军事大模型及其应用分析
  • c++算法题
  • 云原生安全 SaaS :从基础到实践
  • 《Drain日志解析算法》论文阅读笔记
  • MMAction2重要的几个配置参数
  • Windows系统如何查看ssh公钥
  • UniApp+Vue3微信小程序二维码生成、转图片、截图保存整页
  • 8.2 线性变换的矩阵
  • 【2025】嵌入式软考中级部分试题