[OpenCV实战]32 使用OpenCV进行非真实感渲染
目录
1 保边滤波的频域变换
1.1 保边滤波器Edge Preserving Filter
1.1.1 函数调用
1.1.2 edgePreservingFilter结果
1.2 细节增强
1.3 素描滤波器
1.4 风格化滤波器
2 代码
3 参考

有人认为使用高斯内核简单地模糊图像,检测边缘,并将两个图像组合以获得上面所示卡通化图像。虽然在大多数区域中所有图像看起来都很平滑之后,边缘会被保留。结果看起来很荒谬;
这是一个糟糕的主意。通过双边滤波可以完成这项工作,双边滤波可能是计算机视觉中最常用的边缘平滑滤波器,但它很慢。你永远不会在实时应用程序中使用它。我很高兴看到在OpenCV 3中非常快速地实现了保边滤波器。结果与双边滤波非常相似,但速度更快。这是SIGGRAPH 2011论文Domain transform for edge-aware image and video processing实现。论文作者为Eduardo Gastal and Manuel Oliveira。论文见:
http://www.inf.ufrgs.br/~eslgastal/DomainTransform/Gastal_Oliveira_SIGGRAPH2011_Domain_Transform.pdf
保边滤波器详细见:
https://blog.csdn.net/eejieyang/article/details/52333112
1 保边滤波的频域变换
作者Eduardo Gastal在他的项目页面上提供了很多材料来解释论文及其应用。详细链接见:
http://www.inf.ufrgs.br/~eslgastal/DomainTransform/
在OpenCV 3中,本文使用Photo模块下的Computational
Photography子模块中的四个函数实现。以下部分通过示例解释这些功能及其参数。在所有示例中,我们将使用下面的图像作为输入图像。

1.1 保边滤波器Edge Preserving Filter
1.1.1 函数调用
OpenCV中保边滤波器调用函数为edgePreservingFilter。
函数具体调用如下:
C++:
edgePreservingFilter(Mat src, Mat dst, int flags=1, float sigma_s=60, float sigma_r=0.4f)
Python:
dst = cv2.edgePreservingFilter(src, flags=1, sigma_s=60, sigma_r=0.4)
函数具体参数如下:
SRC:8位3通道输入图像
DST:8位3通道输出图像
Flag:保变滤波器类型。取值RECURS_FILTER(递归滤波)= 1和NORMCONV_FILTER(归一化卷积)=2。使用RECURS_FILTER选项比NORMCONV_FILTER快约3.5倍。但NORMCONV_FILTER产生边缘锐化。当不希望锐化时,要求速度应该使用RECURS_FILTER。
sigma_s:范围在0到200之间(详见下文)
sigma_r:范围在0到1之间(详见下文)
参数sigma_s和sigma_r是什么意思?
图像处理和计算机视觉中的大多数平滑滤波器(例如高斯滤波器或盒式滤波器)具有称为sigma_s(用于Sigma_Spatial)的参数,其确定平滑量。典型的平滑滤波器通过其邻居的加权和来替换像素的值。邻域越大,过滤后的图像越平滑。邻域的大小与参数sigma_s成正比。
在保边滤波器中,有两个相互竞争的目标:a)平滑图像b)不平滑边缘/颜色边界。换句话说,我们不能简单地用它的邻居的加权和来代替像素的颜色。相反,我们想要将像素中的颜色值替换为邻域中的像素的平均值,使其也具有与像素类似的颜色。所以我们有两个参数:sigma_s和sigma_r。就像其他平滑滤波器一样,sigma_s控制邻域的大小,sigma_r(用于sigma_range)控制邻域内的不同颜色的平均值。较大的sigma_r导致大面积的恒定颜色区域。
1.1.2 edgePreservingFilter结果
将edgePreservingFilter与RECURS_FILTER一起应用的结果如下所示:

施加edgePreservingFilter与NORMCONV_FILTER的结果如下所示:

正如您所看到的,两个结果非常接近,因此我建议使用 RECURS_FILTER, 因为它比NORMCONV_FILTER快。
1.2 细节增强
顾名思义,过滤器可以增强细节,使图像更清晰。调用参数如下:
C++:
detailEnhance(Mat src, Mat dst, float sigma_s=10, float sigma_r=0.15f)
Python:
dst = cv2.detailEnhance(src, sigma_s=10, sigma_r=0.15)
参数与保边滤波器调用相同。下图显示了结果细节增强过滤器。请注意,整个图像比输入图像更清晰。

1.3 素描滤波器
此过滤器生成的输出看起来像铅笔草图。有两个输出,一个是将滤镜应用于彩色输入图像的结果,另一个是将其应用于输入图像的灰度版本的结果。坦率地说,我对这个过滤器印象不深,因为结果看起来不太棒。调用如下:
C++:
pencilSketch(Mat src, Mat dst_gray, Mat dst_color, float sigma_s=60, float sigma_r=0.07f, float shade_factor=0.02f)
Python:
dst_gray, dst_color = cv2.pencilSketch(src, sigma_s=60, sigma_r=0.07, shade_factor=0.05)
参数与边缘增强滤镜相同。shade_factor(范围0到0.1)是输出图像强度的简单缩放。值越高,结果越亮。
将pencilSketch滤镜应用于输入图像的结果如下所示。


1.4 风格化滤波器
风格化过滤器产生的输出看起来像使用水彩绘制的图像。调用函数如下:
C++:
stylization(Mat src, Mat dst, float sigma_s=60, float sigma_r=0.45f)
Python:
dst = cv2.stylization(src, sigma_s=60, sigma_r=0.07)
参数与边缘增强滤镜相同。应用于输入图像的结果如下所示。

2 代码
所有代码见:
https://github.com/luohenyueji/OpenCV-Practical-Exercise
C++:
#include "pch.h"
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
// Read image 读取图像
Mat im = imread("./image/cow.jpg");
Mat imout, imout_gray;
// Edge preserving filter with two different flags. 保边滤波器
edgePreservingFilter(im, imout, RECURS_FILTER);
imwrite("edge-preserving-recursive-filter.jpg", imout);
edgePreservingFilter(im, imout, NORMCONV_FILTER);
imwrite("edge-preserving-normalized-convolution-filter.jpg", imout);
// Detail enhance filter 边缘增强滤波器
detailEnhance(im, imout);
imwrite("detail-enhance.jpg", imout);
// Pencil sketch filter 素描滤波器
pencilSketch(im, imout_gray, imout);
imwrite("pencil-sketch.jpg", imout_gray);
imwrite("pencil-sketch-color.jpg", imout_gray);
// Stylization filter 风格化滤波器
stylization(im, imout);
imwrite("stylization.jpg", imout);
return 0;
}
Python:
import cv2
# Read image
im = cv2.imread("./image/cow.jpg");
# Edge preserving filter with two different flags.
imout = cv2.edgePreservingFilter(im, flags=cv2.RECURS_FILTER);
cv2.imwrite("edge-preserving-recursive-filter.jpg", imout);
imout = cv2.edgePreservingFilter(im, flags=cv2.NORMCONV_FILTER);
cv2.imwrite("edge-preserving-normalized-convolution-filter.jpg", imout);
# Detail enhance filter
imout = cv2.detailEnhance(im);
cv2.imwrite("detail-enhance.jpg", imout);
# Pencil sketch filter
imout_gray, imout = cv2.pencilSketch(im, sigma_s=60, sigma_r=0.07, shade_factor=0.05);
cv2.imwrite("pencil-sketch.jpg", imout_gray);
cv2.imwrite("pencil-sketch-color.jpg", imout);
# Stylization filter
cv2.stylization(im,imout);
cv2.imwrite("stylization.jpg", imout);
3 参考
https://www.learnopencv.com/non-photorealistic-rendering-using-opencv-python-c/
[OpenCV实战]32 使用OpenCV进行非真实感渲染的更多相关文章
- Unity Shader入门精要学习笔记 - 第14章非真实感渲染
转载自 冯乐乐的 <Unity Shader 入门精要> 尽管游戏渲染一般都是以照相写实主义作为主要目标,但也有许多游戏使用了非真实感渲染(NPR)的方法来渲染游戏画面.非真实感渲染的一个 ...
- [OpenCV实战]48 基于OpenCV实现图像质量评价
本文主要介绍基于OpenCV contrib中的quality模块实现图像质量评价.图像质量评估Image Quality Analysis简称IQA,主要通过数学度量方法来评价图像质量的好坏. 本文 ...
- [OpenCV实战]50 用OpenCV制作低成本立体相机
本文主要讲述利用OpenCV制作低成本立体相机以及如何使用OpenCV创建3D视频,准确来说是模仿双目立体相机,我们通常说立体相机一般是指双目立体相机,就是带两个摄像头的那种(目就是指眼睛,双目就是两 ...
- [OpenCV实战]47 基于OpenCV实现视觉显著性检测
人类具有一种视觉注意机制,即当面对一个场景时,会选择性地忽略不感兴趣的区域,聚焦于感兴趣的区域.这些感兴趣的区域称为显著性区域.视觉显著性检测(Visual Saliency Detection,VS ...
- [OpenCV实战]44 使用OpenCV进行图像超分放大
图像超分辨率(Image Super Resolution)是指从低分辨率图像或图像序列得到高分辨率图像.图像超分辨率是计算机视觉领域中一个非常重要的研究问题,广泛应用于医学图像分析.生物识别.视频监 ...
- [OpenCV实战]45 基于OpenCV实现图像哈希算法
目前有许多算法来衡量两幅图像的相似性,本文主要介绍在工程领域最常用的图像相似性算法评价算法:图像哈希算法(img hash).图像哈希算法通过获取图像的哈希值并比较两幅图像的哈希值的汉明距离来衡量两幅 ...
- [OpenCV实战]46 在OpenCV下应用图像强度变换实现图像对比度均衡
本文主要介绍基于图像强度变换算法来实现图像对比度均衡.通过图像对比度均衡能够抑制图像中的无效信息,使图像转换为更符合计算机或人处理分析的形式,以提高图像的视觉价值和使用价值.本文主要通过OpenCV ...
- [OpenCV实战]30 使用OpenCV实现图像孔洞填充
在本教程中,我们将学习如何填充二值图像中的孔.考虑下图左侧的图像.假设我们想要找到一个二值掩模,它将硬币与背景分开,如下图右侧图像所示.在本教程中,包含硬币的圆形区域也将被称为前景. 请注意,硬币的边 ...
- [OpenCV实战]23 使用OpenCV获取高动态范围成像HDR
目录 1 背景 1.1 什么是高动态范围(HDR)成像? 1.2 高动态范围(HDR)成像如何工作? 2 代码 2.1 运行环境配置 2.2 读取图像和曝光时间 2.3 图像对齐 2.4 恢复相机响应 ...
随机推荐
- 使用request对象进行简单的注册以及信息显示
Request内置对象的使用 概述:request对象主要用于接收客户端发送的请求信息,客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应.封装了用户提交的信息.在 ...
- 齐博x1内容页中下一页上一页的标签
在模板中分别插入如下代码即可 前一页 {:fun('content@prev',$info,20)} 后一页 {:fun('content@next',$info,20)} 复制 其中20代表取标题多 ...
- day51-正则表达式02
正则表达式02 5.4正则表达式语法02 5.4.6捕获分组 详见5.3.3 例子 package li.regexp; import java.util.regex.Matcher; import ...
- 【原创】在RT1050 LittleVgl GUI中嵌入中文输入法框架
时隔一年多终于又冒泡了,哎,随着工作越来越忙,自己踏实坐下来写点东西真是越来越费劲,这篇文章也是准备了好久好久才打算发表出来(不瞒大家,东西做完好久了,文章憋了一年了,当真"高产" ...
- k8s健康检查报错
编辑yaml去掉健康检查 kubectl edit deployment deploymentname 服务恢复
- <一>类,对象,this指针
C++ 类:实体的抽象类型 实体(属性,行为) ->ADT(abstract data type) 类(属性->成员变量,行为->成员方法) OOP语言4大特征 抽象 封装/隐藏(通 ...
- Nginx负载均衡策略的介绍与调优
工作中经常会用到nginx负载均衡这一块,下面对nginx负载均衡策略做个总结.本人在工作中最常用到的负载均衡策略是轮询策略. 在一般情况下,Web中间件最大的作用就是负责对请求进行分发,也就是我们常 ...
- CSS动画-transition/animation
HTML系列: 人人都懂的HTML基础知识-HTML教程(1) HTML元素大全(1) HTML元素大全(2)-表单 CSS系列: CSS基础知识筑基 常用CSS样式属性 CSS选择器大全48式 CS ...
- day17-Servlet06
Servlet06 15.HttpServletResponse 15.1HttpServletResponse介绍 每次HTTP请求,Tomcat都会创建一个HttpServletResponse对 ...
- 高精度加法(Java)
题目描述 高精度加法,相当于 a+b problem,不用考虑负数. 输入格式 分两行输入. a , b ≤ 10^500 输出格式 输出只有一行,代表 a + b 的值. 思路 使用数组进行模拟, ...