【计算机视觉学习】opencv基础(三)编码实现常见滤镜功能

前言

这是计算机视觉学习系列的第三篇文章,讲的是如何通过代码实现一些简单的滤镜功能。文章依然以经典的lena图作为操作示例。

基础版------基础色彩变换形成的风格

基本思路:我们可以通过将图片的色彩进行变换,为它赋予一种新的风格,这是最简单的一种滤镜实现方式。opencv已经提供了如下的一些颜色效果:

还提供了一段代码作为用法示例。相关代码这里就不全部复制粘贴了,感兴趣的uu自行查阅官方文档即可。核心代码其实就是这句:

cpp 复制代码
    applyColorMap(img_in, img_color, COLORMAP_DEEPGREEN);

其中,img_in是输入的原图像的Mat形式,img_color是处理后的Mat形式图像,COLORMAP_DEEPGREEN宏对应于上图列表中的不同的颜色。 以下是笔者认为比较好看的效果,风格也是我给命名的。正所谓萝卜青菜各有所爱,大家当看个乐子就好。

复古风:

明艳风:

冷艳风:

森系风:

进阶版------实现Lomo效果

说起Lomo效果,一些喜欢玩相机的朋友应该不会陌生。以下是摘自网络的介绍:

lomo摄影是指使用专门的lomo相机或者其他相机,通过前期或后期的手段,产生夸张色彩和鲜明特点的图片,以及对画面的理解和表达的摄影。

大致思路及主要代码

首先,我们来看一张实现后的效果图:

那么,如何实现这种效果呢?通过观察,我们可以发现和原图像相比,它有两个特点:

  • 暗指更暗,亮值更亮,形成的对比更明显。
  • 图片中有一个明显的光圈,突出了光圈以内的部分,光圈以外则是阴影。

相应地,可以通过以下步骤来分别实现上述效果:

  • 使用LUT(颜色查找表),利用曲线变幻来操纵红色通道。
    • 产生曲线的公式是这样的: <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 1 + e − x − 0.5 s \frac{1}{1+e^-\frac{x-0.5}{s}} </math>1+e−sx−0.51
    • 对应的编码实现如下:
cpp 复制代码
    const double E = std::exp(1.0);
    Mat lut(1, 256, CV_8UC1);
    for (int i = 0; i < 256; i++)
    {
        float x = (float)i / 256.0;
        lut.at<uchar>(i) = cvRound(256 * (1 / (1 + pow(E, -((x - 0.5) / 0.1)))));
    }
  • 对图像进行暗晕效果处理。通俗来说,就是创建一个黑色背景的白色圆圈,并且对其进行模糊处理,从而实现类似于光晕的效果。编码实现如下:
cpp 复制代码
    Mat halo(img.rows, img.cols, CV_32FC3, Scalar(0.3, 0.3, 0.3));
    circle(halo, Point(img.cols / 2, img.rows / 2), img.cols / 3, Scalar(1, 1, 1), -1);
    blur(halo, halo, Size(img.cols / 3, img.cols / 3));

需要注意的通用点(非仅针对本效果)

那么,如何把上述的高对比图像与光晕相结合呢?其实很简单:把这两个矩阵相乘

但是需要注意元素数据类型转换的问题。因为输入图像的矩阵元素值是整型,而经过模糊处理后的图像元素值范围则在0~1之间:(图源自官方文档)

为了避免精度丢失,可以先将输入图像转为32位浮点数形式,矩阵相乘后再转回去。代码实现如下:

cpp 复制代码
    Mat tmp;
    result.convertTo(tmp, CV_32FC3);
    multiply(tmp, halo, tmp);
    tmp.convertTo(result, CV_8UC3);

参考资料

相关推荐
千宇宙航1 小时前
闲庭信步使用SV搭建图像测试平台:第三十一课——基于神经网络的手写数字识别
图像处理·人工智能·深度学习·神经网络·计算机视觉·fpga开发
Piper蛋窝3 小时前
深入 Go 语言垃圾回收:从原理到内建类型 Slice、Map 的陷阱以及为何需要 strings.Builder
后端·go
whoarethenext4 小时前
使用 C++/OpenCV 和 MFCC 构建双重认证智能门禁系统
开发语言·c++·opencv·mfcc
jndingxin4 小时前
OpenCV CUDA模块设备层-----高效地计算两个 uint 类型值的带权重平均值
人工智能·opencv·计算机视觉
晨同学03275 小时前
opencv的颜色通道问题 & rgb & bgr
人工智能·opencv·计算机视觉
六毛的毛6 小时前
Springboot开发常见注解一览
java·spring boot·后端
AntBlack6 小时前
拖了五个月 ,不当韭菜体验版算是正式发布了
前端·后端·python
31535669136 小时前
一个简单的脚本,让pdf开启夜间模式
前端·后端
uzong6 小时前
curl案例讲解
后端
一只叫煤球的猫7 小时前
真实事故复盘:Redis分布式锁居然失效了?公司十年老程序员踩的坑
java·redis·后端