opencv实践项目-图像卡通化

news2024/11/29 6:30:37

目录

  • 1.如何使图像卡通画
  • 2.铅笔素描滤波器
  • 3. 细节增强滤波器
  • 4. 双边过滤器
  • 5. 铅笔边缘滤波器

1.如何使图像卡通画

我们通常需要执行两个主要步骤将图像转换为卡通图像:边缘检测和区域平滑。
边缘检测的主要目的显然是为了强调图像的边缘,因为卡通图像通常具有良好的边 缘。同时,区域平滑的主要目的是消除颜色边界并减少图像的噪点,使图像像素化程 度降低。
根据不同滤波器,我们可以获得不同的图像卡通化结果。在本文中,将有四个不同的 过滤器:

  • 铅笔素描
  • 细节增强
  • 双边过滤器
  • 铅笔边缘
    接下来,我们将展示如何应用每个过滤器,以及从每个过滤器中获得什么样的结果。

2.铅笔素描滤波器

使用“铅笔素描”滤波器,您的图像将被转换为素描,就像使用铅笔绘制图像一样。下 面是使用OpenCV将图像转换为铅笔素描的完整代码。

int main()
{
    cv::Mat img = cv::imread("/Users/xialz/Downloads/7.jpg");
    cv::Mat gray_img;
    cv::cvtColor(img, gray_img, cv::COLOR_BGR2GRAY);

    cv::Mat gauss_img;
    cv::GaussianBlur(gray_img, gauss_img, Size(25,25), 0);

    cv::Mat cartoon;
    cv::divide(gray_img, gauss_img, cartoon, 255);

    cv::imshow("cartoon", cartoon);
    cv::waitKey(0);

    return 0;
}

令人惊讶的是,使用OpenCV,我们只需三行代码就可以将图像转换成铅笔素描状的图 片。现在让我逐行解释一下该图像发生了哪些变化。 在第一行中,我们使用OpenCV的cvtColor()功能将图像从彩色通道转换为灰度通 道。这很简单,处理的结果是我们将图像变成了灰度图。 接下来,我们使用高斯模糊对图像进行模糊处理。模糊灰度图像,实际上是在平滑图 像,减少图像的噪点。另外,模糊也是我们检测图像边缘的必要步骤。
模糊图像,可以使用OpenCV中的GaussianBlur()功能。我在GaussianBlur() 函数中输入的(25,25)是内核的大小。 由于我们使用高斯模糊,因此内核中像素值的分布遵循正态分布。核数越大,标准偏 差将越大,因此模糊效果越强。
最后一步是将原始灰度图像除以模糊后的灰度图像。这样可以得出两个图像中每个像 素之间的变化率。模糊效果越强,每个像素的值相对于其原点的变化就越大,因此, 它使我们的铅笔素描更加清晰
以下是使用铅笔素描过滤器的结果
在这里插入图片描述

3. 细节增强滤波器

简而言之,“细节增强”滤镜通过锐化图像,平滑颜色以及增强边缘效果为我们提供了 卡通效果。以下是使用此滤镜将您的图像转换成卡通的完整代码。

int main()
{
    cv::Mat img = cv::imread("/Users/xialz/Downloads/7.jpg");
    cv::Mat gray_img;
    cv::cvtColor(img, gray_img, cv::COLOR_BGR2GRAY);

    cv::Mat median_img;
    cv::medianBlur(gray_img, median_img, 3);

    cv::Mat cartoon, edges, color;
    cv::adaptiveThreshold(median_img, edges, 255, BORDER_REPLICATE, cv::ADAPTIVE_THRESH_MEAN_C, 3,0);

    cv::detailEnhance(img, color, 5, 0.5);

    cv::bitwise_and(color, color, cartoon, edges);

    cv::imshow("cartoon", cartoon);
    cv::waitKey(0);

    return 0;
}

第一步与之前相同,我们需要将图像转换为灰度图像。 接下来,不使用高斯模糊,而是应用中值模糊。为此,我们使用OpenCV中的 medianBlur() 函数。中值模糊通过计算与内核重叠的像素值的中值,然后将其中 心像素替换为中值。但是,我们可以根据需要先使用高斯模糊。 接下来,我们需要检测图像的边缘。为此,将自适应阈值与OpenCV中的 adaptiveThreshold() 函数一起应用。自适应阈值的主要目标是根据内核重叠的 像素的平均值,将图像每个区域中的每个像素值转换为黑色或白色。 以下是自适应阈值对模糊图像的影响的可视化结果。

在这里插入图片描述
左:自适应阈值之前—右:自适应阈值之后
为了使图像看起来更清晰,我们可以使用OpenCV中的detailEnhance()函数。我 们需要指定两个参数:
• sigma_s:控制着邻域的大小,该邻域的大小将被加权以替换图像中的像素值。值 越高,邻域越大。这样可以使图像更平滑。
• sigma_r:如果要在平滑图像时保留边缘,这很重要。较小的值只会产生非常相似 的颜色进行平均(即平滑),而相差很大的颜色将保持不变。 最后,我们使用自适应阈值的结果作为掩码。然后,根据蒙版的值合并细节增强的结 果,以创建具有清晰边缘的清晰效果。 以下是“细节增强”过滤器的示例结果。
在这里插入图片描述
细节增强过滤器实现示例

4. 双边过滤器

使用双边滤镜的一大优势是,我们可以在保留边缘的同时使图像和颜色平滑。以下是 通过双边过滤将您的图像转换为卡通图像的完整代码。

int main()
{
    cv::Mat img = cv::imread("/Users/xialz/Downloads/7.jpg");
    cv::Mat gray_img;
    cv::cvtColor(img, gray_img, cv::COLOR_BGR2GRAY);

    cv::Mat median_img;
    cv::medianBlur(gray_img, median_img, 3);

    cv::Mat cartoon, edges, color;
    cv::adaptiveThreshold(median_img, edges, 255, BORDER_REPLICATE, cv::ADAPTIVE_THRESH_MEAN_C, 3,0);

    //cv::detailEnhance(img, color, 5, 0.5);

    cv::bilateralFilter(img, color, 15, 20, 10);

    cv::bitwise_and(color, color, cartoon, edges);

    cv::imshow("cartoon", cartoon);
    cv::waitKey(0);

    return 0;
}

如果仔细看,所有步骤都与“细节增强”过滤器中的步骤相似,但是这次不是使用 detailEnhance() 函数,而是使用openCV中的bilateralFilter()函数。
调用此函数时需要传递的参数与detailEnhance()相同,只多一个附加参数,即内 核大小d。首先,我们指定图像源,然后是d,sigma_s和sigma_r值控制平滑效 果,并保持边缘。 以下是使用双边过滤器的结果示例。
在这里插入图片描述

5. 铅笔边缘滤波器

铅笔边缘滤镜可创建仅包含重要边缘和白色背景的新图像。要应用此滤波器,下面是 完整的代码。

int main()
{
    cv::Mat img = cv::imread("/Users/xialz/Downloads/7.jpg");
    cv::Mat gray_img;
    cv::cvtColor(img, gray_img, cv::COLOR_BGR2GRAY);

    cv::Mat median_img;
    cv::medianBlur(gray_img, median_img, 3);

    cv::Mat cartoon, edges, edges_inv;

    cv::Laplacian(median_img, edges, -1, 3);

    edges_inv = 255 - edges;

    cv::threshold(edges_inv, cartoon, 150, 255, cv::THRESH_BINARY);

    cv::imshow("edges_inv", edges_inv);
    cv::imshow("cartoon", cartoon);
    cv::waitKey(0);

    return 0;
}

前两个步骤与其他过滤器相同。首先,我们将图像转换为灰度图像。接下来,我们使 用大小为25的内核对图像进行模糊处理。 接下来,我们应用拉普拉斯滤波器来检测边缘。根据内核的大小,拉普拉斯滤波器中 的值可以不同。 Laplacian滤波器的工作是,将通过对象内部的灰度级和图像背景强度来突出对象的边 缘。以下是拉普拉斯滤波器应用结果。
在这里插入图片描述
左:拉普拉斯滤波器应用之前—右:拉普拉斯滤波器应用之后
接下来,我们将Laplacian滤波器的结果求反。最后,通过应用openCV中的 threshold()函数,根据指定的阈值将灰度图像转换为全黑或全白。 以下是“铅笔边缘”过滤器的结果示例
在这里插入图片描述
来源于:Python视觉实战项目71讲(更新).pdf,将代码由python改成了c++

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

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

相关文章

银行从业——法律法规

第一章、经济基础知识 第一节、宏观经济分析 【 知识点1】 宏观经济发展目标 宏观经济发展的总体目标一般包括四个: 宏观经济发展的总体目标 衡量指标1、经济增长国内生产总值(GDP)2、充分就业 失业率3、物价稳定通货膨胀率4、国际…

Sangria:类似Nova folding scheme的relaxed PLONK for PLONK

1. 引言 前序博客有: Nova: Recursive Zero-Knowledge Arguments from Folding Schemes学习笔记SuperNova:为多指令虚拟机执行提供递归证明基于Nova/SuperNova的zkVMSangria:PLONK Folding 主要见2023年4月 Geometry团队Nicolas Mohnblat…

多线程编程(1)

本篇重点 了解进程和线程的区别和联系使用Java,实现创建线程的五种写法 目录 使用Java进行多线程编程方法一:继承 Thread, 重写 run方法二: 实现 Runnable, 重写 run方法三: 继承 Thread, 重写 run, 使用匿名内部类方法四: 实现 Runnable, 重写 run, 使用…

【剑指offer】数据结构——数

目录 数据结构——数直接解【剑指offer】43. 1~n 整数中 1 出现的次数【剑指offer】44. 数字序列中某一位的数字【剑指offer】49. 丑数【剑指offer】60. n个骰子的点数【剑指offer】62. 圆圈中最后剩下的数字【剑指offer】64. 求12…n 特殊解——分治法 &#xff1a…

【网络】- TCP/IP四层(五层)协议 - 网际层(网络层) - 划分子网、构造超网

目录 一、概述二、分类IP地址不合理的地方三、划分子网四、无分类编址方法 一、概述 前面的文章介绍了网络层的网际协议IP,介绍了IP地址的定义,知道了IP地址分为网络标识(网络地址)、主机标识(主机地址)两部分,也清楚了最初IP地址是按照分类被…

C++ 迷宫问题

文章目录 题目描述输入描述输出描述示例1 答案:代码讲解: 题目描述 在一个给定大小的迷宫中,有一个起点和一个终点,中间夹杂着一些墙壁 如果能走到终点输出 YES 否则输出 NO 输入描述 迷宫的大小 nm,其中 n 表示行数…

[数据结构 -- C语言] 堆(Heap),你小子就是堆,看我如何透彻的将你拿捏

目录 1、堆的概念及结构 1.1 概念(概念总是重要的) 1.2 结构,分为两种 1.2.1 小堆/小根堆示例 1.2.2 大堆/大根堆示例 2、堆的接口 3、接口实现 3.1 堆的初始化 3.2 堆的销毁 3.3 堆的插入 功能分析: 功能实现&#x…

zabbix动作执行失败 No media defined for user.

问题 zabbix动作执行失败 No media defined for user. 详细问题 解决方案 1(导航栏)用户 → \rightarrow →报警媒介 → \rightarrow →添加 2 选择类型 → \rightarrow →收件人 → \rightarrow →添加 3 更新 解决原因 笔者由于未点击更新钮导…

【计算机网络】3、IO 多路复用:select、poll、epoll、reactor | 阻塞非阻塞、同步异步

文章目录 一、select()1.1 用法1.1 实战 二、poll()2.1 用法2.2 实战 三、阻塞、非阻塞3.1 非阻塞 IO3.1.1 read()3.1.2 write()3.1.3 accept()3.1.4 connect()3.1.5 非阻塞IO select() 多路复用实战 四、epoll()4.1 epoll_create()4.2 epoll_ctl()4.3 epoll_wait()4.4 实战4.…

GAN在图像转译领域的应用-CycleGANPix2Pix

在之前的博客中向大家介绍了生成对抗网络GAN的相关概念以及条件GAN,DCGAN相关内容,需要的小伙伴可以点击以下链接了解~生成对抗网络GAN_生成对抗网络流程_春末的南方城市的博客-CSDN博客生成对抗网络Generative Adversarial Networks(GAN&…

使用Docker安装Guacamole远程网关并配置录像回放

一、参考 guacamole配置guacamole使用Docker安装guacamole在浏览器中播放录像guacamole插件下载 二、环境 操作系统:Anolis OS 8.6 QU1 docker版本:23.0.5 docker compose版本:v2.17.3 docker-image-guacamole:1.5.1 docker-image…

线段树C++详细讲解和个人见解

问题引入 假设有这样的问题&#xff1a;有n个数&#xff0c;m次操作&#xff0c;操作分为&#xff1a;修改某一个数或者查询一段区间的值 数据范围是&#xff08;1 < n, m<1e9)。 这种题大家一看就知道打暴力&#xff0c;但是一看数据范围就知道只能得部分。 我们之前…

STM32F407单片机HAL库CAN2不能接收数据解决方法

最近在使用stm32F407的片子调试can通信&#xff0c;直接在正点原子的代码上修改调试&#xff0c;调试can1的时候&#xff0c;基本没啥问题&#xff0c;收发都正常&#xff0c;使用查询模式和中断模式都可以。但是当修改到can2的时候&#xff0c;可以正常发送数据&#xff0c;但…

@Transactional注解作用,不生效的场景,事务回滚

目录 一、Transactional注解二、注解失效问题1、Transactional 应用在非 public 修饰的方法上2、Transactional 注解属性 rollbackFor 设置错误3、同一个类中方法调用&#xff0c;导致Transactional失效4、捕获异常 三、Transactional回滚1、Transactional2、Transactional(rol…

HUD(抬头显示)的方案介绍

目录 一、基于DLP3030-Q1的HUD电路设计 二、DLP3030-Q1的介绍 三、DLP3030-Q1工作原理 四、DLPC120-Q1DMD 显示控制器 五、TMS320F2802332 位 MCU 六、 HUD显示实例 HUD主板实例 七、HUD的软件环境 一、基于DLP3030-Q1的HUD电路设计 本设计采用了DLP3030-Q1 芯片组&…

H3C IPSec IKE野蛮模式

这里使用H3C模拟器。 H3C IPSec IKE野蛮模式&#xff0c;又称为IKE Main Mode&#xff0c;主要是在第一阶段&#xff08;Phase 1&#xff09;的过程中提供身份保护。它主要用于VPN隧道建立过程中的密钥交换。以下是配置步骤&#xff1a; 创建IKE提案&#xff1a; system-view…

vite源码分析之dev

最近研究socket, 所以就顺便看了一下vite源码, vite的热更新就是根据socket实现的, 所以正好记录一下. 前端任何脚手架的入口,肯定是在package.json文件中,当我们输入script命令时, 会经历什么样的步骤呢? 接下来我们一起来探索一下~~~ 入口-package.json 看下面就是一个普…

【C++】string介绍

String 前言为什么学习string类&#xff1f;string类的常用接口说明string类对象的常见构造析构函数赋值运算符重载[ ] 重载size和length迭代器字符串追加关于容量的函数insert和erasefindreplacec_strrfindfind_first_offind_first_not_offind_last_ofsubstrgetlineto_string …

linux+onenet可视化(图形化步骤)

文章目录 一、ONENET项目搭建1.1 ONENET注册1.2 创建产品与设备1.3 添加数据流 二、可视化配置 OneNET是由中国移动打造的PaaS物联网开放平台。平台能够帮助开发者轻松实现设备接入与设备连接&#xff0c;快速完成产品开发部署&#xff0c;为智能硬件、智能家居产品提供完善的物…

孤儿僵尸守护进程

孤儿僵尸守护进程 1. 孤儿进程&#xff1a;2. 僵尸进程&#xff1a;3. 守护进程&#xff1a;(重点) 1. 孤儿进程&#xff1a; 父进程退出,还没退出的子进程就变成了孤儿进程 不要怕,还有爷爷进程init: 孤儿进程将被init进程所收养&#xff0c;并由init进程对它们完成状态收集…