OpenCV 风格迁移

news2025/4/15 22:35:49

一、引言​
在计算机视觉和图像处理领域,风格迁移是一项令人着迷的技术。它能够将一幅图像(风格图像)的艺术风格,如梵高画作的笔触风格、莫奈的色彩风格等,迁移到另一幅图像(内容图像)上,从而创造出兼具内容图像的主体结构和风格图像艺术风格的全新图像。OpenCV 作为功能强大的计算机视觉库,为实现风格迁移提供了丰富的工具和方法。本文将深入探讨基于 OpenCV 的风格迁移技术,包括其原理、实现步骤以及代码示例,带您领略这一神奇技术的魅力。​
二、风格迁移的原理​
风格迁移的核心思想基于图像的内容特征和风格特征的分离与重组。在数学和计算机视觉的层面,图像可以通过卷积神经网络(CNN)进行特征提取。CNN 的不同层能够提取图像不同层次的特征,较浅层的特征通常对应图像的边缘、纹理等局部细节,这些特征与图像的风格紧密相关;而较深层的特征则更多地反映图像的语义和整体结构,对应图像的内容。​
风格迁移的目标就是在保持内容图像深层内容特征的同时,将风格图像浅层的风格特征融入其中。具体来说,通过计算内容图像和风格图像在 CNN 不同层的特征表示,利用优化算法来调整生成图像的像素值,使得生成图像在内容特征上与内容图像相似,在风格特征上与风格图像相似。常用的衡量这种相似性的方法包括均方误差(MSE)等。例如,计算内容图像和生成图像在特定 CNN 层的特征向量之间的 MSE,以最小化这个误差为目标来更新生成图像,从而使生成图像逐渐逼近内容图像的内容;对于风格特征,则通过计算风格图像和生成图像在多个浅层 CNN 层的 Gram 矩阵之间的 MSE,Gram 矩阵能够反映特征之间的相关性,以此来让生成图像学习到风格图像的风格。

三、代码实现

1. 导入库和打开视频文件

import cv2
cap = cv2.VideoCapture('test.avi')

import cv2:导入 OpenCV 库,用于计算机视觉任务。
cv2.VideoCapture('test.avi'):创建一个视频捕获对象 cap,并打开名为 test.avi 的视频文件,后续可通过该对象读取视频的每一帧。

2. 创建结构元素和背景减除器

kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
fgbg = cv2.createBackgroundSubtractorMOG2()

cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3)):创建一个十字形的结构元素 kernel,其大小为 3x3 像素,用于后续的形态学操作。
cv2.createBackgroundSubtractorMOG2():创建一个基于高斯混合模型的背景减除器 fgbg,用于将视频帧中的前景(运动目标)从背景中分离出来。

3. 视频帧处理主循环

while True:
    ret, frame = cap.read()
    if not ret:
        break
    cv2.imshow('frame', frame)

cap.read():从视频中读取一帧图像。ret 是一个布尔值,表示是否成功读取到帧;frame 是读取到的帧图像。
if not ret: break:如果读取失败(如视频结束),则跳出循环。
cv2.imshow('frame', frame):显示当前读取的原始视频帧。

4. 背景减除

fgmask = fgbg.apply(frame)
cv2.imshow('fgmask', fgmask)

fgbg.apply(frame):使用背景减除器 fgbg 对当前帧 frame 进行处理,得到前景掩码 fgmask。前景掩码是一个二值图像,其中白色区域表示前景(运动目标),黑色区域表示背景。
cv2.imshow('fgmask', fgmask):显示前景掩码图像。

5. 形态学开运算

fgmask_new = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
cv2.imshow('fgmask1', fgmask_new)

cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel):对前景掩码 fgmask 进行形态学开运算,开运算可以去除小的噪声点和连接断开的物体。kernel 是前面创建的结构元素。
cv2.imshow('fgmask1', fgmask_new):显示经过形态学开运算后的前景掩码图像。

6. 轮廓检测

_, contours, h = cv2.findContours(fgmask_new, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

cv2.findContours(fgmask_new, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE):在经过形态学处理后的前景掩码图像 fgmask_new 中查找轮廓。
cv2.RETR_EXTERNAL:表示只检测外部轮廓。
cv2.CHAIN_APPROX_SIMPLE:表示只保留轮廓的端点,压缩水平、垂直和对角方向的多余点,减少内存占用。
contours 是一个列表,包含了检测到的所有轮廓,每个轮廓是一个由点组成的数组。

7. 筛选和绘制轮廓

for c in contours:
    perimeter = cv2.arcLength(c, True)
    if perimeter > 188:
        x, y, w, h = cv2.boundingRect(c)
        fgmask_new_rect = cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

cv2.arcLength(c, True):计算当前轮廓 c 的周长。
if perimeter > 188:筛选出周长大于 188 像素的轮廓,认为这些轮廓对应的是较大的运动目标。
cv2.boundingRect(c):计算当前轮廓 c 的外接矩形,返回矩形的左上角坐标 (x, y) 以及矩形的宽度 w 和高度 h。
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2):在原始视频帧 frame 上绘制矩形框,标记出筛选出的运动目标。矩形框的颜色为绿色 (0, 255, 0),线宽为 2 像素。

8. 显示处理后的帧和等待按键

cv2.imshow('fgmask_new_rect', fgmask_new_rect)
k = cv2.waitKey(1)
if k == 27:
    break

cv2.imshow('fgmask_new_rect', fgmask_new_rect):显示绘制了矩形框的视频帧。
cv2.waitKey(1):等待 1 毫秒,检测是否有按键事件。返回按键的 ASCII 码值。
if k == 27:如果按下的是 Esc 键(ASCII 码值为 27),则跳出循环

9. 释放资源

cap.release()
cv2.destroyAllWindows()

cap.release():释放视频捕获对象,关闭视频文件。
cv2.destroyAllWindows():关闭所有 OpenCV 窗口。

完整代码:

import cv2
cap=cv2.VideoCapture('test.avi')
kernel=cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
fgbg=cv2.createBackgroundSubtractorMOG2()
while True:
    ret,frame=cap.read()
    if not ret:
        break
    cv2.imshow('frame',frame)
    fgmask=fgbg.apply(frame)
    cv2.imshow('fgmask',fgmask)
    fgmask_new=cv2.morphologyEx(fgmask,cv2.MORPH_OPEN,kernel)
    cv2.imshow('fgmask1',fgmask_new)
    _,contours, h = cv2.findContours(fgmask_new, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    for c in contours:
        perimeter = cv2.arcLength(c, True)
        if perimeter > 188:
            x,y,w,h =cv2.boundingRect(c)
            fgmask_new_rect=cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
    cv2.imshow('fgmask_new_rect', fgmask_new_rect)
    k=cv2.waitKey(1)
    if k ==27:
        break

运行结果:

五、应用场景​
艺术创作:艺术家可以利用风格迁移技术快速创作出融合多种艺术风格的作品,为艺术创作带来新的灵感和可能性。例如,将中国传统水墨画的风格迁移到现代摄影作品上,创造出独特的艺术效果。​
图像编辑和设计:在图像编辑软件中,风格迁移可以作为一种特殊的滤镜效果,让普通用户能够轻松将自己的照片转换为具有艺术风格的图像。在平面设计中,设计师可以将特定的风格应用到设计元素上,提升设计作品的独特性和艺术感。​
影视制作:在电影、电视剧的特效制作中,风格迁移可以用于改变场景或角色的视觉风格,营造出特定的氛围和艺术效果。比如,将整个场景的风格迁移为复古油画风格,增强影片的艺术感染力。​
六、总结与展望​
通过 OpenCV 实现的风格迁移技术为我们打开了一扇通往艺术与科技融合的大门。它不仅让我们能够创造出令人惊叹的艺术图像,还在多个领域展现出了巨大的应用潜力。随着计算机技术和算法的不断发展,未来风格迁移技术有望在准确性、效率和效果多样性等方面取得更大的突破。例如,开发更高效的神经网络架构,以实现更快的风格迁移速度;探索更多元化的风格表示方法,使风格迁移能够呈现出更加丰富和细腻的艺术风格。希望本文能激发您对 OpenCV 风格迁移技术的兴趣,让您在计算机视觉和艺术创作的奇妙世界中不断探索。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2334634.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

35.Java线程池(线程池概述、线程池的架构、线程池的种类与创建、线程池的底层原理、线程池的工作流程、线程池的拒绝策略、自定义线程池)

一、线程池概述 1、线程池的优势 线程池是一种线程使用模式,线程过多会带来调度开销,进而影响缓存局部性和整体性能,而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务,这避免了在处理短时间任务时创建与…

Kubernetes nodeName Manual Scheduling practice (K8S节点名称绑定以及手工调度)

Manual Scheduling 在 Kubernetes 中,手动调度框架允许您将 Pod 分配到特定节点,而无需依赖默认调度器。这对于测试、调试或处理特定工作负载非常有用。您可以通过在 Pod 的规范中设置 nodeName 字段来实现手动调度。以下是一个示例: apiVe…

React 获得dom节点和组件通信

通过REF 实例对象的.current属性获得绑定的DOM节点 组件通信 组件通信 1 父传子 父组件传递数据 子组件接受数据 通过pros对象接受 子组件的形参列表props只读 props中数据不可修改 特殊情况 在子传父的过程中没有直接给子组件添加属性,而是向父组件中添加其他…

代码,Java Maven项目打包遇到的环境问题

这几天在写一些Java版本的Langchain4J的 AI 测试case,有一段时间不运行的Java环境,反复出现环境问题,记录下 1、Java编译版本的问题 修改编译版本: 2、在IDE中运行遇到Maven中JDK版本问题 在ide中执行maven命令,遇到下…

fisco-bcos 关于服务bash status.sh启动runing 中但是5002端口监听不到,出错的问题

bash status.sh Server com.webank.webase.front.Application Port 5002 is running PID(4587) yjmyjm-VMware-Virtual-Platform:~/webase-front$ sudo netstat -anlp | grep 5002 没有端口信息输出 此时可以查看log文件夹下的WeBASE-front.log,找到报错信息如下…

linux多线(进)程编程——(5)虚拟内存与内存映射

前言(前情回顾) 进程君开发了管道这门技术后,修真界的各种沟通越来越频繁,这天进程君正与自己的孩子沟通,进程君的孩子说道: “爸爸,昨天我看他们斗法,小明一拳打到了小刚的肚子上&…

SpringBoot 动态路由菜单 权限系统开发 菜单权限 数据库设计 不同角色对应不同权限

介绍 系统中的路由配置可以根据用户的身份、角色或其他权限信息动态生成,而不是固定在系统中。不同的用户根据其权限会看到不同的路由,访问不同的页面。对应各部门不同的权限。 效果 [{"id": 1,"menuName": "用户管理"…

[dp8_子数组] 乘积为正数的最长子数组长度 | 等差数列划分 | 最长湍流子数组

目录 1.乘积为正数的最长子数组长度 2.等差数列划分 3.最长湍流子数组 写代码做到,只用维护好自己的一小步 1.乘积为正数的最长子数组长度 链接:1567. 乘积为正数的最长子数组长度 给你一个整数数组 nums ,请你求出乘积为正数的最长子数…

【图像处理基石】什么是通透感?

一、画面的通透感定义 画面的通透感指图像在色彩鲜明度、空间层次感、物体轮廓清晰度三方面的综合表现,具体表现为: 色彩鲜明:颜色纯净且饱和度适中,无灰暗或浑浊感;层次分明:明暗过渡自然,光…

无锡无人机超视距驾驶证怎么考?

无锡无人机超视距驾驶证怎么考?在近年来,无人机技术的迅猛发展使得无人机的应用场景变得愈发广泛,其不仅在环境监测、农业喷洒、快递配送等领域展现出真金白银的价值,同时也推动了无人机驾驶证的需求。尤其是在无锡,随…

213、【图论】有向图的完全联通(Python)

题目描述 原题链接:105. 有向图的完全联通 代码实现 import collectionsn, k list(map(int, input().split())) adjacency collections.defaultdict(list) for _ in range(k):head, tail list(map(int, input().split()))adjacency[head].append(tail)visited_…

图像形态学操作对比(Opencv)

形态学基于图像的形状进行操作,用于处理二值化图像,主要包括腐蚀和膨胀两种基本操作。这些操作通常用于去除噪声、分隔或连接相邻的元素以及寻找图像中显著的最大点和最小点。 1. 形态学操作 import cv2 import numpy as np import matplotlib.pyplot …

复刻系列-星穹铁道 3.2 版本先行展示页

复刻星穹铁道 3.2 版本先行展示页 0. 视频 手搓~星穹铁道~展示页~~~ 1. 基本信息 作者: 啊是特嗷桃系列: 复刻系列官方的网站: 《崩坏:星穹铁道》3.2版本「走过安眠地的花丛」专题展示页现已上线复刻的网…

Linux:进程理解1(查看进程,创造进程,进程状态)

进程理解 (一)查看进程通过系统调用获取进程标示* (二)创造进程(fork)1. 创造的子进程的PCB代码数据怎么来?2.一个函数为什么有两个返回值?3. 为什么这里会有 两个 id值?…

异形遮罩之QML中的 `OpacityMask` 实战

文章目录 🌧️ 传统实现的问题👉 效果图 🌈 使用 OpacityMask 的理想方案👉代码如下🎯 最终效果: ✨ 延伸应用🧠 总结 在 UI 设计中,经常希望实现一些“异形区域”拥有统一透明度或颜…

如何为您的设计应用选择高速连接器

电气应用的设计过程需要考虑诸多因素,尤其是在设计高速网络时。许多连接器用户可能没有意识到,除了在两个互连之间组装导电线路之外,还需要考虑各种工艺。在建立高速连接并确保适当的信号完整性时,必须考虑蚀刻、公差、屏蔽等因素…

【论文阅读】UniAD: Planning-oriented Autonomous Driving

一、Introduction 传统的无人驾驶采用了区分子模块的设计,即将无人驾驶拆分为感知规划控制三个模块,这虽然能够让无人驾驶以一个很清晰的结构实现,但是感知的结果在传达到规划部分的时候,会导致部分信息丢失,这势必会…

upload-labs二次打

1(前端js绕过) 弹窗,先看看有没有js有,禁用js 禁用后就可以上传php文件了,然后我们就去访问文件,成功 2(MIME绕过) 先上传一个php文件试试,不行,.htaccess不行, 试试MIME类型&am…

提权实战!

就是提升权限,当我们拿到一个shell权限较低,当满足MySQL提权的要求时,就可以进行这个提权。 MySQL数据库提权(Privilege Escalation)是指攻击者通过技术手段,从低权限的数据库用户提升到更高权限&#xff…

ChromeOS 135 版本更新

ChromeOS 135 版本更新 一、ChromeOS 135 更新内容 1. ChromeOS 电池寿命优化策略 为了延长 Chromebook 的使用寿命,ChromeOS 135 引入了一项全新的电池充电限制策略 —— DevicePowerBatteryChargingOptimization,可提供更多充电优化选项&#xff0c…