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

使用 OpenCV 实现哈哈镜效果:让图像“扭曲起来”!

在计算机视觉和图像处理领域,OpenCV 提供了非常强大的图像几何变换能力,不仅可以用于纠正图像,还能制造各种“有趣”的视觉效果。今天,我们就来实现一个经典的“哈哈镜”效果,让图像像在游乐园里一样被拉伸、压缩、扭曲,创造出令人发笑的面部或形体变形。

🎯 什么是“哈哈镜”?

“哈哈镜”是一种非线性扭曲镜面,会在不同区域产生放大或缩小的视觉错觉。我们可以用数学变换模拟出类似的效果,比如:

  • 水平凹面/凸面:图像左右边缘被拉伸或收缩

  • 垂直凹面/凸面:图像上下边缘被拉伸或压缩

  • 中心凹面/凸面:图像向内或向外膨胀

  • 水波扰动:从若干中心点向外扩散波纹,模拟水面晃动感


🔧 技术实现原理

我们将使用 OpenCV 的 remap 函数,它允许我们通过两个映射矩阵 map_xmap_y,定义每个输出像素应该对应输入图像的哪个位置。

关键在于如何构造这两个映射矩阵,让它们产生扭曲效果。


🧪 示例代码:中心凸面效果(鱼眼)

import cv2
import numpy as npdef funhouse_effect(frame):h, w = frame.shape[:2]map_y, map_x = np.indices((h, w), dtype=np.float32)# 计算图像中心cx, cy = w // 2, h // 2# 构造相对坐标dx = map_x - cxdy = map_y - cyr = np.sqrt(dx**2 + dy**2)r_max = np.max(r)# 控制扭曲强度k = 0.0008  # 越大越扭曲(中心凸出)scale = 1 + k * (r**2)  # 非线性放大map_x = cx + dx * scalemap_y = cy + dy * scale# 保证映射范围合法map_x = np.clip(map_x, 0, w - 1)map_y = np.clip(map_y, 0, h - 1)return cv2.remap(frame, map_x, map_y, interpolation=cv2.INTER_LINEAR)frame = cv2.imread("face.jpg")
output = funhouse_effect(frame)
cv2.imwrite("distorted.jpg", output)


📚 多种哈哈镜效果

你可以基于上面的思路实现更多效果:

效果类型扭曲方式示意说明
水平凹面scale = 1 - k * ((x-cx)/cx)^2中心宽、边窄
垂直凸面scale = 1 + k * ((y-cy)/cy)^2中心鼓起
中心凹面scale = 1 - k * r^2边缘大、中心小
随机水波扰动sin(r * 频率 + 相位) 叠加扰动水波纹起伏感


🔄 通用框架:FrameObject 封装

为了在实时视频或处理多个帧时使用,我们可以封装为如下类:

class FrameObject:def __init__(self):self.mode = 'random_wave'  # 选择效果def do(self, frame, device):h, w = frame.shape[:2]map_y, map_x = np.indices((h, w), dtype=np.float32)cx, cy = w // 2, h // 2dx = map_x - cxdy = map_y - cyr = np.sqrt(dx**2 + dy**2)if self.mode == 'center_fisheye':scale = 1 + 0.0006 * (r**2)map_x = cx + dx * scalemap_y = cy + dy * scaleelif self.mode == 'horizontal_cave':scale = 1 - 0.0012 * ((dx / cx) ** 2)map_x = cx + dx * scalemap_y = map_yelif self.mode == 'random_wave':for _ in range(np.random.randint(1, 4)):wave_cx = np.random.randint(w // 4, 3 * w // 4)wave_cy = np.random.randint(h // 4, 3 * h // 4)ddx = map_x - wave_cxddy = map_y - wave_cyrr = np.sqrt(ddx**2 + ddy**2)phase = np.random.uniform(0, 2 * np.pi)displacement = 8 * np.sin(rr * 0.05 + phase)map_x += displacement * (ddx / (rr + 1e-6))map_y += displacement * (ddy / (rr + 1e-6))map_x = np.clip(map_x, 0, w - 1)map_y = np.clip(map_y, 0, h - 1)return cv2.remap(frame, map_x, map_y, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT)


🎥 应用场景

  • 互动镜像设备(如景区搞笑自拍)

  • 视频滤镜制作(社交媒体)

  • 教学演示图像几何变换原理

  • 图像增强(用作数据增强的一种方式)


🧠 总结

使用 OpenCV,我们可以轻松实现各种非线性图像变换来模拟“哈哈镜”效果。本质上是通过构建合适的映射矩阵 map_xmap_y,来控制每个像素的位置变换。配合正弦波、极坐标缩放、指数函数等,你可以无限创造各种扭曲方式。


如果你对某种特定变形方式感兴趣,或者想将其用于实时视频流、交互系统中,欢迎留言交流!🎉

相关文章:

使用 OpenCV 实现哈哈镜效果:让图像“扭曲起来”!

在计算机视觉和图像处理领域,OpenCV 提供了非常强大的图像几何变换能力,不仅可以用于纠正图像,还能制造各种“有趣”的视觉效果。今天,我们就来实现一个经典的“哈哈镜”效果,让图像像在游乐园里一样被拉伸、压缩、扭曲…...

pikachu靶场 暴力破解

学习中参考的博客如下 pikachu靶场暴力破解专题-CSDN博客 1,基于表单的暴力破解 出现了一个登录页面 解题步骤:抓包,发到bp里,右键发到Intruder,因为有两个位置要爆破,所以选择集群炸弹攻击&#xff…...

鸿蒙开发:应用上架第三篇,配置签名信息打出上架包

前言 本文基于Api13 经过前面两篇文章,我们获取到了密钥和证书请求文件以及最终的发布证书和发布证书Profile文件,可以说,所有的签名信息文件,我们都已经完成了,正所谓,万事俱备只欠东风,这篇文…...

基于R语言的贝叶斯网络模型实践技术应用:开启科研新视角

在现代科研领域,变量间的因果关系推断是生态学、环境科学、医学等多学科研究的核心问题。然而,传统的统计学方法往往只能揭示变量间的相关关系,而非因果关系。贝叶斯网络作为一种结合图论与统计学理论的新型模型,不仅能够统合多种…...

第五章 GPT模块配置

由于GPT配置需要和Irq和Mcu进行配合设置(GPT可以由芯片外设中的GTM和GPT12实现,这次是以GTM为实现)。 1 GTM外设时钟配置 首先需要对MCU组件进行配置,配置GTM的时钟,需要参照GTM的CMU时钟树。 下图时钟树的CLS0_CLK为MCU(McuClockSettingConfig_0中的 McuSTMFrequency )f…...

虚拟机NAT模式获取不到ip

虚拟机NAT模式获取不到ip 如图所示 解决方案: 先查看NetworkManager是否启动 systemctl status NetworkManager如果没启动就启动一遍 使用DHCP手动获取一遍ip sudo dhclient ens33成功得到ip 这是后遇到了另一个问题,ip释放后,不能自动…...

Docker的网络介绍

网络简单介绍 在介绍 Docker 的网络模式之前,先简单说下我们在使用 Vmware 虚拟机中的网络模式,形成对比,更好理解。 1、Vmware 中的网络模式 1.1、VMnet0(桥接模式) 虚拟机通过宿主机的物理网卡直接连接到外部网络…...

Nginx负载均衡配置详解

在Nginx中配置负载均衡主要通过 upstream 模块实现,结合反向代理将请求分发到多个后端服务器。以下是详细配置步骤和案例解析: 一、基础配置 1. 配置语法 http {upstream backend_servers {# 负载均衡策略server backend1.example.com;server backend2.example.com;server …...

关于 Web 漏洞原理与利用:4. 文件上传漏洞

定义:文件上传漏洞是指应用程序允许用户上传文件,但没有严格校验上传文件的类型、内容、路径等属性,导致攻击者可以上传并执行恶意代码。 绕过方式: 前端绕过 1. 前端限制的原理 前端限制上传文件类型的常见方式有三种&#xf…...

(6)python爬虫--selenium

文章目录 前言一、初识selenium二、安装selenium2.1 查看chrome版本并禁止chrome自动更新2.1.1 查看chrome版本2.1.2 禁止chrome更新自动更新 2.2 安装对应版本的驱动程序2.3安装selenium包 三、selenium关于浏览器的使用3.1 创建浏览器、设置、打开3.2 打开/关闭网页及浏览器3…...

MCU 上电不启动的常见原因分析与排查思路

在开发过程中,“MCU 上电不运行”是我们经常遇到的问题之一。但客户对此类问题的描述往往较为模糊,仅简单表示“产品不工作”或“怀疑 MCU 没有运行”,这给我们现场排查带来了较大的挑战。即便工程师到达现场,往往也无法迅速定位问…...

Spark Core 源码关键环节的深度解析

以下是对 Spark Core 源码关键环节的深度解析,包括核心组件启动与调度机制、Shuffle与调度系统、RDD高级机制。每个环节都细化到具体方法、逻辑、源码片段,附有流程图思路与速记口诀,便于记忆和理解。 一、核心组件启动与调度机制 1. RpcEnv…...

net Core》》包与库 LibMan、NPM

LibMan 资料 NPM 资料 在 Visual Studio 中使用 npm package.json 保存之后 vs会自动下载的。 注意:如果您没有看到 node_modules 文件夹,请确保在 Visual Studio 解决方案资源管理器中启用了“显示所有文件”选项 要卸载该库,您只需从 …...

数学建模,机器决策人建模

目录 数学建模 微分方程 动态系统建模 时间序列分析 概述 指数衰减 随机漂移 总结 曲线拟合 最优化方法 梯度下降法 概率建模(如贝叶斯建模、马尔可夫过程、MDP/POMDP) 等 贝叶斯建模 贝叶斯定理 优势 马尔可夫过程 马尔可夫过程的分类…...

FFmpeg中使用Android Content协议打开文件设备

引言 随着Android 10引入的Scoped Storage(分区存储)机制,传统的文件访问方式发生了重大变化。FFmpeg作为强大的多媒体处理工具,也在不断适应Android平台的演进。本文将介绍如何在FFmpeg 7.0版本中使用Android content协议直接访…...

SQL查询, 响应体临时字段报: Unknown column ‘data_json_map‘ in ‘field list‘

Overridepublic AjaxResult list(AgentPageReqVO pageReqVO, Integer pageNo, Integer pageSize) {// 1. 查询数据库获取代理列表List<AgentDO> list agentMapper.selectPage(pageReqVO).getList();// 如果结果为空&#xff0c;直接返回空分页结果if (CollectionUtils.i…...

OpenCv高阶(十四)——LBPH人脸识别

文章目录 前言一、LBPH原理1. LBP&#xff08;局部二值模式&#xff09;特征提取2. 图像分块处理3. 生成直方图4. 人脸识别&#xff08;匹配阶段&#xff09;5. LBPH的特点6. 变种与优化 二、LBPH人脸识别简单实现&#xff08;一&#xff09;LBPH人脸识别1、图像读取&#xff0…...

C#开发利器:SharpBoxesCore全解析

SharpBoxesCore 是一个基于 C# 的开源开发工具库&#xff0c;旨在为开发者提供一系列常用功能模块和辅助类&#xff0c;以提高开发效率、减少重复代码编写&#xff0c;并增强项目的可维护性和扩展性。该库集成了多种实用工具类和通用扩展方法&#xff0c;适用于桌面应用、Web 项…...

回表是数据库概念,还是mysql的概念?

主键索引没有列&#xff0c;根据耳机索引去查主键索引&#xff0c;又没有查表&#xff0c;为啥叫回表呢&#xff1f; “回表”这个词&#xff0c;其实算是数据库里的一个通用概念&#xff0c;不过它最常见的应用场景是在 MySQL 的 InnoDB 引擎里&#xff0c;所以很多人一提起回…...

49、c# 能⽤foreach 遍历访问的对象需满足什么条件?

在 C# 中&#xff0c;要使用 foreach 循环遍历一个对象&#xff0c;该对象必须满足以下条件之一&#xff1a; 1. 实现 IEnumerable 或 IEnumerable 接口 非泛型版本&#xff1a;System.Collections.IEnumerable public class MyCollection : IEnumerable {private int[] _da…...

DL00987-基于深度学习YOLOv11的红外鸟类目标检测含完整数据集

提升科研能力&#xff0c;精准识别红外鸟类目标&#xff01; 完整代码数据集见文末 针对科研人员&#xff0c;尤其是研究生们&#xff0c;是否在鸟类目标检测中遇到过数据不够精准、处理困难等问题&#xff1f;现在&#xff0c;我们为你提供一款基于深度学习YOLOv11的红外鸟类…...

07 接口自动化-用例管理框架之pytest单元测试框架

文章目录 一、pytest用例管理框架&#xff08;单元测试框架&#xff09;二、pytest简介三、pytest的最基本的测试用例的规则四、运行方式1.主函数方式2.命令行方式3.通过pytest.ini的配置文件运行 五、pytest 默认执行测试用例的顺序六、跳过测试用例1.无条件跳过 pytest.mark.…...

Flutter 中 build 方法为何写在 StatefulWidget 的 State 类中

Flutter 中 build 方法为何写在 StatefulWidget 的 State 类中 在 Flutter 中&#xff0c;build 方法被设计在 StatefulWidget 的 State 类中而非 StatefulWidget 类本身&#xff0c;这种设计基于几个重要的架构原则和实际考量&#xff1a; 1. 核心设计原因 1.1 生命周期管理…...

多技术栈 iOS 项目的性能调试实战:从 Flutter 到 Unity(含 KeyMob 工具实测)

多技术栈 iOS 项目的性能调试实战&#xff1a;从 Flutter 到 Unity 随着移动端开发日趋多元化&#xff0c;iOS 项目中纯 Objective-C/Swift 已不再是唯一选择。越来越多团队采用 Flutter、React Native、Unity、WebView 混合等方案构建 App。这种“技术栈混合”带来灵活性的同…...

Base64加密解密

Base64 是一种基于 64 个可打印字符来表示二进制数据的编码方式&#xff0c;常用于需要通过文本协议传输二进制数据的场景&#xff08;如 URL、邮件&#xff09;。以下是不同场景下生成 Base64 编码的方法&#xff1a; 一、编程语言实现 Python import base64# 字符串转Base…...

程序设计基础----排序(2)

1、冒泡排序 #include <stdio.h>#define N 1000 int arr[N];/* 对长度为n的数组arr执行冒泡排序 */ void bubbleSort(int arr[], int n);/* 打印长度为n的数组arr */ void printArray(int arr[], int n);void swap(int *xp, int *yp) {int temp *xp;*xp *yp;*yp temp…...

C++:vector容器

vector容器与array容器相似&#xff0c;但vector容器是动态的&#xff0c;可以自动扩容。 使用方法和一些注意如下&#xff1a; #include<iostream> #include<vector> using namespace std;int main() {vector<char> vec { a,b,c,d };vec[4] e;//不能以此…...

十四、Hive 视图 Lateral View

作者&#xff1a;IvanCodes 日期&#xff1a;2025年5月20日 专栏&#xff1a;Hive教程 在Hive中&#xff0c;我们经常需要以不同于原始表结构的方式查看或处理数据。为了简化复杂查询、提供数据抽象&#xff0c;以及处理复杂数据类型&#xff08;如数组或Map&#xff09;&#…...

Frp Dockr Mysql内网映射

用 FRP 远程暴露 Mac mini 上的 Docker-MySQL&#xff08;含 Ubuntu frps 安装和 macOS 客户端配置&#xff09; 一、环境说明 服务器&#xff08;公网&#xff09;&#xff1a;Ubuntu 22.04 frps内网设备&#xff1a;macOS (Mac mini) frpc Docker MySQL目标&#xff1a;…...

PHP 扇形的面积(Area of a Circular Sector)

圆形扇区或圆形扇区是圆盘上由两个半径和一个圆弧围成的部分&#xff0c;其中较小的区域称为小扇区&#xff0c;较大的区域称为大扇区。让我们看看这个图&#xff0c;试着找出扇区&#xff1a; 在该图中&#xff0c;绿色阴影部分是扇形&#xff0c;“r”是半径&#xff0c;“th…...

物业后勤小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的物业后勤小程序源码&#xff0c;它为物业管理提供了高效便捷的解决方案。 该源码功能丰富&#xff0c;涵盖房屋认证、家人认证&#xff0c;保障社区居住安全&#xff1b;支持报事报修、装修申请&#xff0c;方便业主与物业沟通&#xff1b;还…...

git基础操作

当远程仓库迁移到一个新的组下面时&#xff0c;你需要在本地仓库中更新远程仓库的URL&#xff0c;以便与新的远程仓库关联。以下是详细步骤&#xff1a; 获取新的远程仓库URL&#xff1a; 首先&#xff0c;你需要从GitLab或相关平台获取新组下的仓库的新URL。通常&#xff0c;仓…...

鸿蒙HarmonyOS 【ArkTS组件】通用属性-背景设置

&#x1f4d1;往期推文全新看点&#xff08;附带最新鸿蒙全栈学习笔记&#xff09; 嵌入式开发适不适合做鸿蒙南向开发&#xff1f;看完这篇你就了解了~ 鸿蒙岗位需求突增&#xff01;移动端、PC端、IoT到底该怎么选&#xff1f; 分享一场鸿蒙开发面试经验记录&#xff08;三面…...

java 在用redis 的时候,如何合理的处理分页问题? redis应当如何存储性能最佳

在 Java 中使用 Redis 处理用户表分页时&#xff0c;需结合其数据结构特性优化存储和查询 1. 数据结构设计 场景需求 用户表字段&#xff1a;id, name, age, register_time&#xff08;注册时间&#xff09;分页要求&#xff1a;按注册时间倒序分页展示&#xff0c;每页 10 条…...

分类预测 | Matlab实现PNN概率神经网络多特征分类预测

分类预测 | Matlab实现PNN概率神经网络多特征分类预测 目录 分类预测 | Matlab实现PNN概率神经网络多特征分类预测分类效果代码功能算法流程程序设计参考资料分类效果 代码功能 该代码实现了一个基于**概率神经网络(PNN)**的多分类任务,核心功能如下: 数据预处理 读取Exce…...

spring-retry

学习链接 【SpringBoot】spring-retry(重试机制) 【Spring】Spring Retry CSDN有点可恶啊&#xff0c;拿着别人的文章&#xff0c;要开VIP才能看...

RTMP协议解析【二】

文章目录 RTMP协议解析【二】RTMP消息消息的格式Basic HeaderMessage HeaderExtended Timestamp RTMP协议解析【二】 本专栏重点负责介绍RTMP协议的理论部分&#xff0c; 跳过定义&#xff0c;协议与其他协议的优缺点对比&#xff0c;协议的拓展与改进&#xff0c;协议的历史发…...

WebGL2混合与雾

混合技术 一、混合基本技术 混合技术就是将两个片元调和&#xff0c;主要通过各种测试将准备进入帧缓冲&#xff08;源片元&#xff09;与帧缓冲中原有片元&#xff08;目标片元&#xff09;按照设定的比例加权计算出最终片元的颜色值 。 两种常用 组合 &#xff1a; 源因子…...

Windows Docker笔记-扩展

docker扩展知识点 开放容器端口 背景&#xff0c;有一个docker Centos7镜像&#xff0c;运行容器后&#xff0c;想要通过22端口远程这个容器 创建容器时开放映射端口&#xff0c;将容器的22端口映射到本地的22端口 docker run -p <宿主机端口>:<容器端口> 镜像名…...

【C++ Primer 学习札记】智能指针

1&#xff09;std::unique_ptr&#xff08;独占所有权&#xff09; 特点&#xff1a; 独占资源的所有权&#xff0c;同一时间只能有一个 unique_ptr 指向特定对象。 不可复制&#xff0c;但可以通过 std::move 转移所有权。 轻量级&#xff0c;几乎无额外开销&#xff08;与…...

【嵌入式人工智能产品开发实战】(二十二)—— 政安晨:改造小智AI开发智能体硬件(案例:移植PowerManager后麦克风不工作)

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 目录 确定你硬件的关键点 案例分析 &#x1f50d; 一、关键代码分析 ✅ 1. power_save_…...

Taro Error: chunk common [mini-css-extract-plugin]

目录 一、问题描述 二、解决方案 一、问题描述 taro项目编译时抛出一下异常&#xff1a; Error: chunk common [mini-css-extract-plugin] Conflicting order. Following module has been added: * css ./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[4].oneOf…...

【深度学习】多目标融合算法(六):渐进式分层提取模型PLE(Progressive Layered Extraction)

目录 一、引言 二、PLE&#xff08;Progressive Layered Extraction&#xff0c;渐进式分层提取模型&#xff09; 2.1 技术原理 2.2 技术优缺点 2.3 业务代码实践 2.3.1 业务场景与建模 2.3.2 模型代码实现 2.3.3 模型训练与推理测试 2.3.4 打印模型结构 三、总结 一…...

ping、tcpping、psping、paping、hping的区别

ping、tcpping、psping、paping、hping的区别 这些工具都是用于网络测试的&#xff0c;但它们在功能和协议上有所不同&#xff0c;适用于不同的场景。 ping 基本功能&#xff1a; 发送ICMP echo请求包&#xff0c;并等待接收echo应答包&#xff0c;从而判断网络是否连通&…...

【Redis8】最新安装版与手动运行版

1. 下载 Redis 百度网盘 2. 解压后直接运行 redis-server.exe 3. 使用安装版 双击 install_redis_service.bat 输入安装路径&#xff08;请提前创建好安装路径&#xff09;后直接回车下一步直接回车即可&#xff0c;因为是使用配置模板文件为默认解压出来的&#xff0c;然后…...

前端(小程序)学习笔记(CLASS 1):组件

1、小程序中组件的分类 小程序中的组件也是由宿主环境提供的&#xff0c;开发者可以基于组件快速搭建出漂亮的页面结构。官方把小程序的组件分为了9大类&#xff0c;分别是&#xff1a; * 视图容器&#xff0c;* 基础内容&#xff0c;* 表单组件&#xff0c;* 导航组件 媒体…...

Python MD5加密算法脚本

基本概念 MD5&#xff08;Message Digest Algorithm 5&#xff09;是一种常用的哈希函数&#xff0c;用于将任意长度的数据转换为固定长度的哈希值&#xff0c;通常为128位&#xff08;16字节&#xff09;。 特点 不可逆性&#xff1a;无法从哈希值还原出原始数据。无论原始…...

Python数据分析实战:Pandas高效处理Excel数据指南

目录 引言&#xff1a;为什么选择Pandas处理Excel&#xff1f; 一、环境搭建与数据读取 1.1 基础环境配置 1.2 数据高效载入技巧 二、数据清洗核心战术 三、数据加工实战案例 3.1 销售数据透视分析 3.2 异常值检测 3.3 跨表关联分析 四、性能优化秘籍 4.1 大文件处理…...

使用Starrocks制作拉链表

5月1日向ods_order_info插入3条数据&#xff1a; CREATE TABLE ods_order_info(dt string,id string COMMENT 订单编号,total_amount decimal(10,2) COMMENT 订单金额 ) PRIMARY KEY(dt, id) PARTITION BY (dt) DISTRIBUTED BY HASH(id) PROPERTIES ( "replication_num&q…...

【npm】npm命令大全

掌握 NPM&#xff1a;前端与 Node.js 开发者必备命令大全 NPM (Node Package Manager) 无疑是现代 JavaScript 开发的基石。无论是前端项目还是 Node.js 后端服务&#xff0c;NPM 都扮演着管理依赖、执行脚本、发布模块等关键角色。熟悉并熟练使用 NPM 命令&#xff0c;能够极…...