我的编程空间,编程开发者的网络收藏夹
学习永远不晚

OpenCV实现图像背景虚化效果原理详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

OpenCV实现图像背景虚化效果原理详解

0 写在前面

相信用过相机的同学都知道虚化特效,这是一种使焦点聚集在拍摄主题上,让背景变得朦胧的效果,例如本文最后实现的背景虚化效果

相机虚化特效背后的原理是什么?和计算机视觉有什么关系?本文带你研究这些问题。

1 小孔成像

小学我们就知道,没有光就不存在图像,为了产生图像,场景必须有一个或多个、直接或间接的光源。

如图所示,光照主要分为三类:

  • 散射
  • 直接光照
  • 漫反射

在获得光源后,将产生从物体到检测平面的光线。

由于从物体上某点A出发存在无数条四散的光线到达检测平面,因此可以认为A的成像点A’均匀地分布在成像平面上,同理其他点亦然。所以这种情况下,检测平面上是无数张物体图像的混叠,导致成像模糊甚至无法成像。

面对一张白纸上看不到你的脸,不是因为白纸上没有来自于你的光线,而是因为来自于你不同部分的光线在白纸上产生了重叠,不信你试试?

那如何在白纸上成像?

其实非常简单,采用小学就尝试过的小孔成像

本质上小孔相当于一个滤光器,仅保留从物点发出的少数光线,此时应能获得清晰的图像。

2 光学成像

小孔成像的缺陷是成像光线较少,亮度低。为了既能获得较多光线,又不让像点四散在检测面上造成影像重叠,引入具有聚光性的透镜。透镜成像与小孔成像的本质都是避免因像点四散导致的无法成像,前者利用聚光,后者则利用滤光。

现代相机在应用上通常使用透镜成像,但不管是透镜成像还是小孔成像,都是计算机视觉研究的基本模型和假设,例如透视几何相机内参矩阵畸变修正等等,因此本节对于建立机器视觉的研究思维很有帮助。

3 虚化效果

介绍完前面的基础知识,终于开始图像虚化特效的原理啦!

理想透镜应保证光线聚焦于一点——焦点,这个点不会产生任何成像混叠,图像最清晰。在焦点前后光线开始四散,形成不同程度的成像重叠区域,称为弥散圆,对于人眼而言,在一定范围内影象产生的模糊是不能辨认的,不能辨认的弥散圆范围称为容许弥散圆

当对被摄主体平面调焦时,因为容许弥散圆的存在,在一定离焦范围内,成像仍然清晰,这个范围称为焦深。调整成像面和镜头距离,使成像面处于焦深内,物体可以清晰成像的过程,称为对焦。

类似地,对被摄物体而言,位于调焦物平面前后的能相对清晰成像的景物间纵深距离称为景深。图像虚化效果就和这个景深有关系!

  • 景深越小,被摄物体前后能清晰成像的范围越小,也就相应地出现朦胧虚化的效果
  • 景深越大,被摄物体前后能清晰成像的范围越大,也就没有虚化效果

如何调节景深?记住一句话:光圈越大景深越小,所以拿手机拍照的时候,大光圈也就代表了虚化效果!

所以下次有机会给女生拍照的话,请先确认

“请问你喜欢小景深还是大景深?”

4 代码实战

相机背景虚化特效在图像处理中可以采用引导滤波器实现,源码如下。

//引导滤波器
Mat guidedFilter(Mat& class="lazy" data-srcMat, Mat& guidedMat, int radius, double eps)
{
    class="lazy" data-srcMat.convertTo(class="lazy" data-srcMat, CV_64FC1);
    guidedMat.convertTo(guidedMat, CV_64FC1);
    // 计算均值
    Mat mean_p, mean_I, mean_Ip, mean_II;
    boxFilter(class="lazy" data-srcMat, mean_p, CV_64FC1, Size(radius, radius));                      // 生成待滤波图像均值mean_p 
    boxFilter(guidedMat, mean_I, CV_64FC1, Size(radius, radius));                   // 生成引导图像均值mean_I   
    boxFilter(class="lazy" data-srcMat.mul(guidedMat), mean_Ip, CV_64FC1, Size(radius, radius));      // 生成互相关均值mean_Ip
    boxFilter(guidedMat.mul(guidedMat), mean_II, CV_64FC1, Size(radius, radius));   // 生成引导图像自相关均值mean_II
    // 计算相关系数、Ip的协方差cov和I的方差var------------------
    Mat cov_Ip = mean_Ip - mean_I.mul(mean_p);
    Mat var_I = mean_II - mean_I.mul(mean_I);
    // 计算参数系数a、b
    Mat a = cov_Ip / (var_I + eps);
    Mat b = mean_p - a.mul(mean_I);
    // 计算系数a、b的均值
    Mat mean_a, mean_b;
    boxFilter(a, mean_a, CV_64FC1, Size(radius, radius));
    boxFilter(b, mean_b, CV_64FC1, Size(radius, radius));
    // 生成输出矩阵
    Mat dstImage = mean_a.mul(class="lazy" data-srcMat) + mean_b;
    return dstImage;
}

关于引导滤波器的相关原理我们下次再开新的章节阐述。

主函数内调用滤波器即可,效果如文首所示。

int main()
{
    Mat resultMat; 
    Mat vclass="lazy" data-srcImage[3], vResultImage[3];
    Mat vResultImage[3];    
    Mat class="lazy" data-srcImage = imread("1.jpg");
    imshow("源图像", class="lazy" data-srcImage);
    // 对源图像进行通道分离,并对每个分通道进行引导滤波
    split(class="lazy" data-srcImage, vclass="lazy" data-srcImage);
    for (int i = 0; i < 3; i++)
    {
        Mat tempImage;
        vclass="lazy" data-srcImage[i].convertTo(tempImage, CV_64FC1, 1.0 / 255.0);
        Mat cloneImage = tempImage.clone();
        Mat resultImage = guidedFilter(tempImage, cloneImage, 5, 0.3);
        vResultImage[i] = resultImage;
    }
    // 将分通道导向滤波后结果合并
    merge(vResultImage, 3, resultMat);
    imshow("背景虚化特效", resultMat);
    waitKey(0);
    return 0;
}

一个小小的图像虚化特效,背后牵扯出光学成像的各种原理,构建了计算机视觉模型的地基。正如我们每个人一样,也许你觉得自己很渺小,说不定也是别人的中流砥柱呢!

到此这篇关于OpenCV实现图像背景虚化效果原理详解的文章就介绍到这了,更多相关OpenCV图像背景虚化内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

OpenCV实现图像背景虚化效果原理详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python基于纹理背景和聚类算法实现图像分割详解

这篇文章将详细讲解Python图和基于纹理背景的图像分割和聚类算法实现图像分割效果,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
2023-01-03

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录