【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格式。…...
ESXi 自动加入 vCenter:Kickstart 脚本高效部署指南
在虚拟化集群部署中,手动将 ESXi 主机加入 vCenter Server 不仅繁琐,还容易出现配置失误,尤其适用于大规模集群搭建场景。本教程将介绍一种基于 Pyvmomi 工具的优化方案,无需依赖外部复杂环境,直接通过 ESXi Kickstart…...
从 Rule、Spec 到 Harness:AI Coding 的渐进式建设路径
文章目录前言第一阶段:Rule —— 给 AI 立规矩,就像教小孩认字第二阶段:Spec —— 先写文档再写代码,就像盖房子先画图纸第三阶段:Harness —— 自动验证与反馈,就像给 AI 配了个质检员这三个阶段是啥关系&…...
如何快速激活Windows和Office:KMS_VL_ALL_AIO新手指南
如何快速激活Windows和Office:KMS_VL_ALL_AIO新手指南 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO KMS_VL_ALL_AIO是一款开源的智能激活脚本工具,专为Windows和Office…...
AI专著撰写秘籍大公开!实用工具推荐,让写作从此轻松起飞
对于许多研究者来说,撰写学术专著面对的最大挑战,往往源于“有限的精力”与“无限的需求”之间的矛盾。写一本专著通常需要耗费3到5年,甚至更长的时间,而研究者们还需兼顾教学、科研与学术交流等多项任务,能够用于写作…...
2026届最火的五大AI辅助论文网站实测分析
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 有着自动剖析研究领域热点能力的AI开题报告工具,是依托自然语言处理与知识图谱技…...
G-Helper:重构华硕设备性能管理的轻量级解决方案 | 玩家与商务人士必备工具
G-Helper:重构华硕设备性能管理的轻量级解决方案 | 玩家与商务人士必备工具 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, …...
Shell脚本自动化监控:用curl的-w参数批量检查网站健康状态(附完整脚本)
Shell脚本自动化监控:用curl的-w参数批量检查网站健康状态 最近在维护公司十几个微服务时,我发现手动检查每个接口状态简直是一场噩梦。直到重新审视了curl的-w参数,才意识到这个被低估的功能能带来怎样的效率革命。本文将分享如何用Shell脚本…...
【开发小技巧】手把手调用腾讯 ClawHub 镜像分页搜索接口
【开发小技巧】手把手调用腾讯 ClawHub 镜像分页搜索接口 一、接口简介 如果你想在自己的项目里快速实现「技能列表检索」能力,这个接口非常适合做数据源。 接口地址:https://lightmake.site/api/skills请求方式:GET功能说明:分页…...
AI净界RMBG-1.4使用技巧:让抠图效果更完美的几个小方法
AI净界RMBG-1.4使用技巧:让抠图效果更完美的几个小方法 1. 为什么抠图效果有时不够理想? 即使是目前最先进的RMBG-1.4模型,在某些特殊情况下也可能出现边缘不够完美的情况。这通常不是模型本身的问题,而是由于输入图片的特性导致…...
8大AI核心概念,让你秒懂智能体、多智能体系统、RAG、工作流、微调、函数调用、MCP和A2A!
本文介绍了8个AI核心概念,包括智能体(Agent)和多智能体系统(Multi-Agent System),以及如何通过RAG(Retrieval-Augmented Generation)、工作流(Work Flow)、微…...
