一、前言

今天介绍一个有趣的demo,结合之前图像空域滤波边缘检测的知识,实现图像卡通化,通过实现的过程,可以发现几种图像边缘检测和差异和图像滤波的性质

Demo来自《Mastering OpenCV with Practical ComputerVision Projects》(目前没见到中文版),可以在网上下载Ebook。
附Github地址:https://github.com/MasteringOpenCV/code

二、图像卡通化实现原理解析

实现原理:

图像卡通化的过程,实际上是对图像的内容部分进行平滑处理,对边缘部分锐化处理,使得图像内容更加光滑、边缘更加突出

步骤:

  1. 通过边缘检测滤波器获得灰度图像的边缘特征,阈值化后可得黑白素描图
  2. 通过双边滤波器多次迭代获得柔化图像,使平滑区域更光滑
  3. 将(1)中素描图作为掩膜叠加到(2)中柔化图像得卡通化图像

以上是图像卡通化的一般步骤,在实际过程中,我们还需要考虑以下问题:

Q: 若原图含噪声,应该如何处理?
A: 我们知道无论是一阶还是二阶微分算子,都对噪声敏感,在边缘检测之前,一定要先进行去噪处理,空域内图像平滑通常有五种方法:线性滤波(均值滤波、方框滤波和高斯滤波)、非线性滤波(中值滤波和双边滤波),在这里一般选择非线性滤波中的中值滤波,(1)中值滤波能够有效去除边缘孤立噪声点而不会平滑边缘特征,(2)中值滤波能够保持边缘的锐度,利于后面边缘检测。

Q: 边缘检测滤波器如何选择?
A: 常用的边缘检测算子有:一阶微分算子(Sobel、Scharr)、二阶微分算子(Canny、Laplace),关于这几种检测算子的使用,书籍原文给出了解释:

There are many different edge detection flters, such as Sobel, Scharr, Laplacian filters, or Canny-edge detector. We will use a Laplacian edge flter since it produces edges that look most similar to hand sketches compared to Sobel or Scharr, and that are quite consistent compared to a Canny-edge detector, which produces very clean line drawings but is affected more by random noise in the camera frames and the line drawings therefore often change drastically between frames.

原文选择Laplacian算子,我的理解有以下两点:
(1)像Sobel等一阶微分算子,通过XY方向上的灰度梯度来估算边缘信息,并不能将图像边缘与背景信息区分开来,如Sobel算子提取的边缘通常过于“细致”而不符合主观视觉上的真实图像边缘,相较之下,Laplacian、Canny等二阶微分算子往往能得到更加合理的边缘,看起来也更有“素描”的感觉。
(2)Canny算子检测的边缘连续性更好,轮廓也更清晰,但是它容易受随机噪声影响,相较之下,Laplacian算子的噪声抑制效果要更好,而相机自然拍摄的图片多少含有随机噪声,所以选择Laplacian算子是最好的选择。

Q:为什么选择双边滤波器柔化图像?
A:(1)双边滤波器是一种非线性滤波方法,有效结合图像的空间邻近度和像素值相似度的优势,用它柔化图像的原因是(1)同时考虑了空间信息和灰度相似性,同时达到保边去噪的目的;(2)对局部信息的保持效果好

Q:双边滤波的速度很慢,如何优化?
A:为了加速滤波过程,可以先缩小图像,再进行双边滤波,处理完成后,恢复原始尺寸,处理效果与直接原图滤波差不多,但是效率却提高了几倍。

三、实现卡通化图像源码

通过以上的分析过程,就可以写出代码,部分实现细节在代码中讲解:

#include<opencv2/opencv.hpp>
using namespace cv;void cartoonify(Mat& src,Mat& dst, const char* typeName){Mat gray;cvtColor(src,gray,CV_RGB2GRAY);medianBlur(gray,gray,5); //去噪if(typeName == "Scharr"){Mat edge1=Mat(gray.size(),CV_8U);Mat edge2;Scharr(gray,edge1,CV_8U,1,0,1,0,BORDER_DEFAULT); //X方向差分运算 Scharr(gray,edge2,CV_8U,0,1,1,0,BORDER_DEFAULT); //Y方向差分运算 edge1 += edge2; //整体Scharredge1.copyTo(gray);}else if(typeName == "Canny"){Canny(gray,gray,80,160,3); }else{Laplacian(gray, gray, CV_8U, 5);}Mat mask(src.size(),CV_8U);threshold(gray,mask,120,255,THRESH_BINARY_INV);//medianBlur(mask,mask,3); imshow("mask",mask);//对原始图像双边滤波Size smallSzie(src.cols/2,src.rows/2);Mat s_src=Mat(smallSzie,src.type());resize(src,s_src,smallSzie,0,0,INTER_LINEAR);Mat tmp=Mat(smallSzie,CV_8UC3);int iterator=7;for(int i=0;i<iterator;i++){int ksize=9;double sigmaColor=9;double sigmaSpace=7;bilateralFilter(s_src,tmp,ksize,sigmaColor,sigmaSpace);bilateralFilter(tmp,s_src,ksize,sigmaColor,sigmaSpace);}Mat b_src;resize(s_src,b_src,src.size(),0,0,INTER_LINEAR);//掩膜叠加dst=Mat(src.size(),src.type(),Scalar::all(0)); //初始化//dst.setTo(0);b_src.copyTo(dst,mask);
}int main()
{Mat src=imread("C:/Users/Administrator/Desktop/beauty.jpg");if(!src.data){printf("Load failture...");return 0;}resize(src,src,Size(600,400),0,0,INTER_LINEAR);Mat dst;cartoonify(src,dst,"Canny");imshow("cartoonImg_Scharr",dst);waitKey(0);return 0;
}

结果如下:
(1)使用Scharr边缘检测算子时:

(1)使用Canny边缘检测算子时:

(1)使用Lapcian边缘检测算子时:

整体来看Laplacian算子实现效果最好,Canny算子检测的边缘轮廓最清晰且连贯性好,但是视觉上边缘掩膜痕迹太重了(即素描轮廓过于清晰)。由于原图无噪声,所以从噪声方面考虑Canny算子实现的效果还是挺好的!

OpenCV实现图像卡通化相关推荐

  1. OpenCV-Python实战(番外篇)——OpenCV实现图像卡通化

    OpenCV-Python实战(番外篇)--OpenCV实现图像卡通化 前言 图像卡通化 完整代码 更多卡通化效果展示 相关链接 前言 在博文<OpenCV-Python实战(4)--OpenC ...

  2. 基于Opencv的图像卡通化

    基于Opencv的图像卡通化 基于Opencv的图像卡通化 铅笔素描效果 国画效果 抽象效果 基于Opencv的图像卡通化 主要工具是高斯滤波器.细节增强滤波器.双边滤波.拉普拉斯滤波器. 铅笔素描效 ...

  3. opencv 图片边缘渐变_基于OpenCV的图像卡通化

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本期将创建一个类似于Adobe Lightroom的Web应用程序 ...

  4. python多张照片拼成一张人脸,使用OpenCV实现人脸图像卡通化的示例代码

    引言 通过前面的文章我们已经了解到OpenCV 是一个用于计算机视觉和机器学习的开源 python 库.它主要针对实时计算机视觉和图像处理.它用于对图像执行不同的操作,这些操作使用不同的技术对图像进行 ...

  5. opencv实践项目-图像卡通化

    目录 1.如何使图像卡通画 2.铅笔素描滤波器 3. 细节增强滤波器 4. 双边过滤器 5. 铅笔边缘滤波器 1.如何使图像卡通画 我们通常需要执行两个主要步骤将图像转换为卡通图像:边缘检测和区域平滑 ...

  6. 使用OpenCV实现人脸图像卡通化

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 引言 通过前面的文章我们已经了解到OpenCV 是一个用于计算机视 ...

  7. 【Python-OpenCV 人脸图像卡通化】

    Python-OpenCV 人脸图像卡通化 前言 一.边缘检测和滤波 二.使用步骤 1.引入库 2.处理图像 3.展示结果 总结 前言 OpenCV 提供了丰富的图像滤波和边缘检测的算法,可利用其为照 ...

  8. 《Learning to Cartoonize Using White-box Cartoon Representations》图像卡通化论文解析

    这篇文章收录于CVPR2020,在图像卡通化上效果不错. github地址:https://github.com/SystemErrorWang/White-box-Cartoonization 那么 ...

  9. 一个免费的在线图像卡通化网站

    网站地址: Cartoonizer 这个是[CVPR2020]Learning to Cartoonize Using White-box Cartoon Representations论文的在线De ...

最新文章

  1. PAT(甲级)2021年春季考试 7-3 Structure of Max-Heap
  2. 重绘(repaint)与渲染(reflow)
  3. 1.19 String、StringBuffer和StringBuilder类的区别
  4. LSMW、BDC、CATT 区别
  5. 机器学习之数据预处理——特征编码(标签编码,独热编码)
  6. 好文!研究生高效阅读的五大原则
  7. 《开源框架那点事儿14》:教计算机程序解数学题
  8. 多窗口下的批量操作脚本 - 利用win32gui和WindowSpy++简单实现目标窗口前置
  9. VS出现error LNK2005,error C4430,error C2011
  10. vue+Gantt如何在vue中使用甘特图,绘制任务进度
  11. [Unity3D] [学习] Unity3D的官方文档
  12. oppoK9Pro游戏性能怎么样
  13. 网证你申请了吗?怎么使用?
  14. 表现与数据分离、web语义化的理解
  15. 电脑下载软件用什么软件好?安卓手机下载软件用哪个软件好?IDM下载器说:在做的都是弟弟
  16. ionic中的slide-box
  17. 问:女孩学编程好就业吗?
  18. 记一次cnpm install的各种报错深刻记忆
  19. 【MOS】如何利用RMAN可传输表空间迁移数据库到不同字节序的平台(文档 ID 1983639.1)...
  20. Web安全之:WebShell的获取与查杀

热门文章

  1. 分年级分难度英语单词词典ACCESS数据库
  2. Bluemix实战教程: CF命令学习分享
  3. Android Room数据库升级
  4. Win7/Win10安装AutoCAD+CASS
  5. 基于SSM的台球室俱乐部管理系统Spring+SpringMVC+MyBatis
  6. v48.05 鸿蒙内核源码分析(信号生产) | 年过半百 活力十足 | 百篇博客分析HarmonyOS源码
  7. 重中之重基础-Redis介绍
  8. 小程序将替代APP?还差得太远!
  9. 关于“996”的个人看法
  10. 离线搭建git服务器(Gogs)