【python】OpenCV—Fun Mirrors
文章目录
- 1、准备工作
- 2、原理介绍
- 3、代码实现
- 4、效果展示
- 5、参考
1、准备工作
pip install vacm
2、原理介绍
在OpenCV中,VCAM 库是一个用于简化创建三维曲面、定义虚拟摄像机、设置参数以及进行投影任务的工具。它特别适用于实现如哈哈镜等图像变形效果。
一、VCAM 库的功能
VCAM 库的主要功能包括:
-
创建三维曲面:用户可以根据需要定义一个三维曲面,这个曲面将作为虚拟镜面的基础。
-
定义虚拟摄像机:用户可以设置虚拟摄像机的各种参数,如焦距、位置等,以模拟不同的拍摄效果。
-
投影与重映射:将三维曲面上的点投影到虚拟摄像机的成像平面上,并生成相应的二维点。这些二维点可以用于图像的重映射,从而实现图像的变形效果。
二、使用VCAM库实现哈哈镜效果
-
获取图像并创建网格:首先,获取待处理的图像,并创建一个与图像大小相同的网格。这个网格将用于表示三维曲面上的点。
-
定义三维曲面:通过修改网格中每个点的Z坐标值,来定义一个凹凸不平的三维曲面。这可以通过各种数学函数来实现,如正弦函数、余弦函数等。
-
创建虚拟摄像机并投影:使用VCAM库创建一个虚拟摄像机,并将定义好的三维曲面投影到虚拟摄像机的成像平面上。这一步将生成对应的二维点集。
-
图像重映射:根据投影得到的二维点集,使用OpenCV的remap函数对原始图像进行重映射。重映射的过程将根据二维点集的位置关系,将原始图像中的每个像素点映射到新的位置,从而实现图像的变形效果。
三、代码示例
以下是一个使用Python和VCAM库实现哈哈镜效果的示例代码:
import cv2
import numpy as np
from vcam import vcam, meshGen # 读取图像
img = cv2.imread('your_image.jpg')
H, W = img.shape[:2] # 创建虚拟摄像机
c1 = vcam(H=H, W=W) # 创建网格
plane = meshGen(H, W) # 定义三维曲面(例如,使用正弦函数来创建波浪形的曲面)
plane.Z = 10 * np.sin((plane.X / plane.W) * 2 * np.pi * 10) # 获取三维曲面上的点
pts3d = plane.getPlane() # 将三维点投影到二维图像坐标
pts2d = c1.project(pts3d) # 构建映射函数
map_x, map_y = c1.getMaps(pts2d) # 应用映射函数进行图像重映射
output = cv2.remap(img, map_x, map_y, interpolation=cv2.INTER_LINEAR) # 显示结果
cv2.imshow('Funny Mirror', output)
cv2.waitKey(0)
cv2.destroyAllWindows()
四、注意事项
-
安装VCAM库:在使用VCAM库之前,需要确保已经正确安装了该库。如果使用的是Python,可以通过pip等包管理工具进行安装。
-
调整参数:在使用VCAM库时,可以通过调整虚拟摄像机的参数、三维曲面的定义等来实现不同的变形效果。用户可以根据需要进行多次尝试和调整。
-
性能考虑:对于较大的图像或复杂的变形效果,图像重映射的过程可能会比较耗时。因此,在实际应用中需要考虑性能问题,并采取相应的优化措施。
综上所述,OpenCV的VCAM库是一个功能强大的工具,可以用于实现各种有趣的图像变形效果。通过合理使用该库,用户可以轻松地创建出具有创意和趣味性的图像作品。
3、代码实现
# FunnyMirrorsImages.py
import cv2
import numpy as np
import math
from vcam import vcam, meshGenpaths = ["./chess.jpeg", "./1.jpg", "./2.jpg"]for mode in range(8):for i, path in enumerate(paths):# 读取输入图像img = cv2.imread(path)img = cv2.resize(img, (300, 300))H, W = img.shape[:2]# 创建虚拟相机对象c1 = vcam(H=H, W=W)# 创建表面对象plane = meshGen(H, W)# 我们生成一面镜子,其中对于每个 3D 点,其 Z 坐标定义为 Z = F(X,Y)if mode == 0:plane.Z += 20 * np.exp(-0.5 * ((plane.X * 1.0 / plane.W) / 0.1) ** 2) / (0.1 * np.sqrt(2 * np.pi))elif mode == 1:plane.Z += 20 * np.exp(-0.5 * ((plane.Y * 1.0 / plane.H) / 0.1) ** 2) / (0.1 * np.sqrt(2 * np.pi))elif mode == 2:plane.Z -= 10 * np.exp(-0.5 * ((plane.X * 1.0 / plane.W) / 0.1) ** 2) / (0.1 * np.sqrt(2 * np.pi))elif mode == 3:plane.Z -= 10 * np.exp(-0.5 * ((plane.Y * 1.0 / plane.W) / 0.1) ** 2) / (0.1 * np.sqrt(2 * np.pi))elif mode == 4:plane.Z += 20 * np.sin(2 * np.pi * ((plane.X - plane.W / 4.0) / plane.W)) + 20 * np.sin(2 * np.pi * ((plane.Y - plane.H / 4.0) / plane.H))elif mode == 5:plane.Z -= 20 * np.sin(2 * np.pi * ((plane.X - plane.W / 4.0) / plane.W)) - 20 * np.sin(2 * np.pi * ((plane.Y - plane.H / 4.0) / plane.H))elif mode == 6:plane.Z += 100 * np.sqrt((plane.X * 1.0 / plane.W) ** 2 + (plane.Y * 1.0 / plane.H) ** 2)elif mode == 7:plane.Z -= 100 * np.sqrt((plane.X * 1.0 / plane.W) ** 2 + (plane.Y * 1.0 / plane.H) ** 2)else:print("Wrong mode selected")exit(-1)# 提取生成的 3D 平面pts3d = plane.getPlane()# 在虚拟相机中投影(捕捉)平面pts2d = c1.project(pts3d)# 为基于网格的扭曲生成映射函数。map_x, map_y = c1.getMaps(pts2d)# 生成输出output = cv2.remap(img, map_x, map_y, interpolation=cv2.INTER_LINEAR)output = cv2.flip(output, 1)cv2.imshow("Funny Mirror", output)cv2.imshow("Input and output", np.hstack((img, np.zeros((H, 2, 3), dtype=np.uint8), output)))# 取消注释以下行以保存输出# cv2.imwrite("Mirror-effect-%d-image-%d.jpg"%(mode+1,i+1),np.hstack((img,np.zeros((H,2,3),dtype=np.uint8),output)))cv2.waitKey(0)
4、效果展示
输入图片
plane.Z += 20 * np.exp(-0.5 * ((plane.X * 1.0 / plane.W) / 0.1) ** 2) / (0.1 * np.sqrt(2 * np.pi))
plane.Z += 20 * np.exp(-0.5 * ((plane.Y * 1.0 / plane.H) / 0.1) ** 2) / (0.1 * np.sqrt(2 * np.pi))
plane.Z -= 10 * np.exp(-0.5 * ((plane.X * 1.0 / plane.W) / 0.1) ** 2) / (0.1 * np.sqrt(2 * np.pi))
plane.Z -= 10 * np.exp(-0.5 * ((plane.Y * 1.0 / plane.W) / 0.1) ** 2) / (0.1 * np.sqrt(2 * np.pi))
plane.Z += 20 * np.sin(2 * np.pi * ((plane.X - plane.W / 4.0) / plane.W)) + 20 * np.sin(2 * np.pi * ((plane.Y - plane.H / 4.0) / plane.H))
plane.Z -= 20 * np.sin(2 * np.pi * ((plane.X - plane.W / 4.0) / plane.W)) - 20 * np.sin(2 * np.pi * ((plane.Y - plane.H / 4.0) / plane.H))
plane.Z += 100 * np.sqrt((plane.X * 1.0 / plane.W) ** 2 + (plane.Y * 1.0 / plane.H) ** 2)
plane.Z -= 100 * np.sqrt((plane.X * 1.0 / plane.W) ** 2 + (plane.Y * 1.0 / plane.H) ** 2)
5、参考
- https://github.com/kaustubh-sadekar/FunMirrors
- https://github.com/kaustubh-sadekar/VirtualCam
- OpenCV进阶(11)使用 OpenCV实现哈哈镜
相关文章:

【python】OpenCV—Fun Mirrors
文章目录 1、准备工作2、原理介绍3、代码实现4、效果展示5、参考 1、准备工作 pip install vacm2、原理介绍 在OpenCV中,VCAM 库是一个用于简化创建三维曲面、定义虚拟摄像机、设置参数以及进行投影任务的工具。它特别适用于实现如哈哈镜等图像变形效果。 一、VC…...
QT IEEE754 16进制浮点数据转成10进制
IEEE754标准转换QT代码 qtcreator使用的ieee754标准的4字节数组与浮点数之间的转换方法,ieee754的4位数组如果转换成二进制后,大体结构是: 位序号12-910-32意义 符号位, 正数为0,负数为1. 指数位, 指数是…...

无人机+视频推流直播EasyCVR视频汇聚/EasyDSS平台在森林防护巡检中的解决方案
随着科技的飞速发展,无人机技术在各个领域的应用日益广泛,特别是在森林防护与巡检方面,无人机以其独特的优势,为传统林业管理带来了革命性的变化。本文将探讨无人机在森林防护巡检中的解决方案,分析其工作原理、优势及…...

Rancher—多集群Kubernetes管理平台
目录 一、Rancher 简介1.1 Rancher 和 k8s 的区别 二、Rancher 安装及配置2.1 安装 rancher2.2 登录 Rancher 平台2.3 Rancher 管理已存在的 k8s 集群2.4 创建名称空间 namespace2.5 创建 Deployment 资源2.6 创建 service2.7 Rancher 部署监控系统 一、Rancher 简介 Rancher …...
使用多IP香港站群服务器对网站管理seo优化提升排名有益处
在网站管理和优化中,选择合适的服务器是至关重要的。针对某些特定需求,使用多IP香港站群服务器可以带来明显的益处。本文将探讨使用多IP香港站群服务器 对网站管理的明显益处,并介绍其中的关键要点和优势。 I. 理解多IP香港站群服务器 1. 多I…...

网管平台(基础篇):网管系统的重要性
网管系统的核心地位:数字世界的稳定舵手 在信息技术日新月异的今天,网络如同一条无形的纽带,将世界紧密相连。然而,这条纽带背后隐藏着无数复杂的节点与链路,如何确保它们高效、稳定地运行,成为了一个亟待解…...

Ubuntu20.04下安装多CUDA版本,以及后续切换卸载
本方案的前提是假设机子上已经有一个版本的cuda,现在需要支持新的torch2.1.2和torchvision0.16.2,于是来安装新的cuda 一、选择版本 如果我想安装支持torch2.1.2的cuda版本,到官网(https://pytorch.org/get-started/previous-ve…...
图像处理高频面试题及答案
目录 高频面试题及答案1. 什么是图像处理?2. 什么是图像的分辨率?3. 图像的颜色空间是什么?4. 什么是边缘检测,为什么重要?5. 解释一下图像增强的常见方法。6. 什么是图像的直方图?7. 什么是图像的去噪声?8. 什么是图像分割,常用的方法有哪些?9. 图像滤波的目的是什么…...

尤雨溪都打赏的虚拟列表组件,到底有多强
尤雨溪都打赏的虚拟列表组件,到底有多强? 在前端开发中,性能优化永远是绕不开的主题。今天就带你看看 vue-virtual-scroller,一款让你滚动页面时流畅得像火箭一样的 Vue 组件。本文将简单介绍这个组件的主要功能、技术特点&#x…...
FrameWork使用EfCore数据库映射举例
Microsoft.EntityFrameworkCore新的版本不支持FrameWork框架。 这里举例使用旧版本实现数据存取 首先下载 Microsoft.EntityFrameworkCore 版本控制在2.1.14以下 同样下载Microsoft.EntityFrameworkCore.sqlite 举例时间记录 public class RunTimeInfo{[Key]public int Id { g…...

汽车与航空领域的功能安全对比:ISO 26262-6 与 DO-178C 的差异浅析
ISO 26262-6 和 DO-178C (航空系统与设备认证中的软件考量)。是汽车和航空领域分别广泛应用的软件安全标准。它们的共同目标是确保系统软件可靠性,减少系统软件故障对生命安全的威胁,但在具体的软件安全方案和规范实施上存在明显的…...
linux命令之lspci用法
lspci 显示当前主机的所有PCI总线信息 补充说明 lspci命令 用于显示当前主机的所有PCI总线信息,以及所有已连接的PCI设备信息。 语法 lspci(选项)选项 -n:以数字方式显示PCI厂商和设备代码; -t:以树状结构显示PCI设备的层次…...

虚幻闪烁灯光材质
创建一个材质 材质域改成光照函数 , Time让材质动起来 参数B用来控制速度 , Sine 让灯光闪烁 , Frac 增加了闪烁细节 把材质放到灯光材质上 效果还是挺不错的! 可以用于一些恐怖游戏~...
UNION ALL函数用法
文章目录 1. 什么是 UNION ALL?2. UNION ALL 的特点2.1 不去重2.2 性能更优2.3 列数和数据类型 3. 示例应用3.1 基本示例3.2 结合其他 SQL 功能3.3 使用子查询3.4 转换操作(leetcode真题) 4. 注意事项5. 结论 在数据库查询中, 合并多个结果集是一个常见…...

JavaWeb合集14-WebSocket
十四、WebSocket WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信,浏览器和服务器只需要完成一次握手, 两者之间就可以创建持久性的连接,并进行双向数据传输。 HTTP协议和WebSocket协议对比: HTTP是短连…...
Vue快速嵌入百度地图,避坑提效指南
Vue快速嵌入百度地图,避坑提效指南 在Vue项目中引用百度地图并没有高德地图那么方便,但是项目要用,这里分享下找到的方法,方便使用到的时候能快速接入,避雷避坑! 新建bmap.js文件 export default {init: f…...

深入理解售后派单管理系统,功能优势一览
售后派单管理系统优化售后服务流程,提升响应速度、运营效率和服务质量。ZohoDesk等系统通过自动化派单、实时调度监控等功能,助力企业赢得竞争优势。适用于电子产品、汽车、IT及房地产等行业。 一、什么是售后派单管理系统 售后派单管理系统是一种专门用…...
一文读懂K8S的PV和PVC以及实践攻略
一文读懂K8S的PV和PVC以及实践攻略 Kubernetes(K8S)作为当前云原生和微服务架构的首选平台,凭借其强大的容器编排和管理能力,迅速成为一线大厂分布式平台的标配技术。在Kubernetes中,持久化存储是一个核心问题&#x…...
在react-native中如何获取View的漏出比例和漏出时间
写在前面 最近在项目中遇到了一个这样的需求:给一个模块做埋点,要求埋点的触发时机是当模块露出50%且停留300毫秒才进行上报 开搞 首先要有一个View <View></View>然后在View里定义一个ref <View ref { viewRef }></View>然…...

谷歌新安装包文件形式 .aab 在UE4中的打包原理
摘要 本文学习了aab的基本概念以及UE4中产生aab的构建原理。 从官网了解基本概念 官网:Android Developers 1、什么是aab? .aab包形如: 2021年7月,在Google Play应用程序中,已经有数千个应用程序率先跟进了AAB格式。…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...