【图像处理】使用 OpenCV 将您的照片变成卡通

图像到卡通

一、说明

        在当今世界,我们被图像和视频所包围。从社交媒体到广告,图像已成为一种强大的交流媒介。但是你有没有想过,如果你能把你的照片变成卡通会发生什么?想象一下,为您最喜欢的照片创建动画版本,或者将肖像转换为异想天开的插图。

        在本文中,我们将探讨如何使用 Python 中的 OpenCV 库将图像转换为卡通。OpenCV 是一个功能强大的计算机视觉库,为图像和视频处理提供了广泛的功能,包括边缘检测、颜色转换和过滤。我们将使用这些工具在给定的图像上创建卡通效果。

        为此,我们将首先导入必要的模块并加载输入图像。接下来,我们将对图像应用一系列转换,包括边缘检测、颜色量化和双边滤波。最后,我们将结合这些转换,在输入图像上创建卡通效果。在整篇文章中,我们将提供有关如何使用 OpenCV 实现每个转换的分步说明。在本文结束时,您将清楚地了解如何使用 OpenCV 在任何输入图像上创建卡通效果。因此,让我们深入了解如何使用OpenCV将图像转换为卡通!

二、导入必要的库 

import cv2
import numpy as np
import os

2.1 代码说明:

  • import cv2导入 OpenCV 库,该库为图像和视频处理提供了广泛的功能。
  • import numpy as np导入 NumPy 库,这是一个流行的库,用于在 Python 中处理数组和矩阵。
  • import os导入操作系统模块,该模块提供了一种与文件系统交互的方法。

总的来说,这段代码导入了在 Python 中使用 OpenCV 执行图像处理的必要模块。

2.2 在 Python 中使用 OpenCV 显示输入图像:

img = cv2.imread('original_picture.jpg')
cv2.imshow("original", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

原始图片

2.3 代码说明:

  • cv2.imread('original_picture.jpg')将名为“original_picture.jpg”的输入图像加载到名为 的变量中。这是您想要的图片的名称。img
  • cv2.imshow("original", img) 在标题为“原始”的窗口中显示输入图像。
  • cv2.waitKey(0)等待按键。参数 0 表示程序将无限期等待,直到按下某个键。
  • cv2.destroyAllWindows() 关闭所有打开的窗口。

三、使用 K 均值聚类进行颜色量化:

def color_quantization(img, k):
# Transform the imagedata = np.float32(img).reshape((-1, 3))# Determine criteriacriteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 0.001)# Implementing K-Meansret, label, center = cv2.kmeans(data, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)center = np.uint8(center)result = center[label.flatten()]result = result.reshape(img.shape)return result

3.1 功能说明:

  • 该函数采用两个参数 — 输入图像和聚类数。imgk
  • 输入图像首先使用 NumPy 库转换为像素值的二维数组。
  • 为 K-Means 聚类分析算法确定一组条件,包括聚类中心的最大迭代次数和最小变化。
  • K 均值聚类分析算法使用 cv2.kmeans() 函数应用于数据,具有指定数量的聚类和条件。如果变量发生变化,该函数将生成具有不同数量颜色簇的新量化图像。较小的值 将导致具有较少颜色的量化图像,而较大的值 将导致具有更多颜色的量化图像。kkk
  • 生成的聚类中心使用 NumPy 函数转换为 8 位整数。np.uint8()
  • 原始图像被展平为像素值的一维数组,每个像素被分配到其最近的聚类中心。
  • 然后将生成的像素值数组重新塑造回原始输入图像的形状。
  • 生成的量化图像作为函数的输出返回。

3.2 创建边缘遮罩:

def edge_mask(img, line_size, blur_value):gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)gray_blur = cv2.medianBlur(gray, blur_value)edges = cv2.adaptiveThreshold(gray_blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, line_size, blur_value)return edges

3.3 功能说明:

  • 该函数有三个参数——输入图像、蒙版中线条的大小和应用于灰度图像的模糊程度。如果变量发生变化,掩码中线条的大小也会相应更改。较小的值将导致更细的线条,而较大的值将导致较粗的线条。imgline_sizeblur_valueline_size
  • 首先使用该函数将输入图像转换为灰度。cv2.cvtColor()
  • 然后使用具有指定 .如果变量发生变化,应用于灰度图像的模糊级别将发生变化。较小的值将导致较少的模糊,而较大的值将导致更多的模糊。cv2.medianBlur()blur_valueblur_value
  • 通过使用该功能对模糊的灰度图像应用自适应阈值来创建边缘遮罩。这种自适应阈值方法根据每个像素周围局部邻域中像素值的平均值计算每个像素的阈值。cv2.adaptiveThreshold()
  • 生成的边缘掩码作为函数的输出返回。

四、从图像生成铅笔素描:

line_size = 7
blur_value = 7edges = edge_mask(img, line_size, blur_value)
cv2.imwrite('pencil_sketch.jpg', edges)
cv2.imshow('pencil sketch', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

铅笔素描

4.1 代码说明:

  • 代码首先将 和 的值设置为 7。如果 和 的值发生变化,则生成的铅笔素描将受到影响。较小的 值将导致线条越细,而较大的值将导致线条变粗。同样,较小的 值将导致较少的模糊,而较大的值将导致更多的模糊,这可能会影响铅笔草图的整体外观。line_sizeblur_valueline_sizeblur_valueline_sizeblur_value
  • 使用具有指定和 的函数从输入图像生成边缘掩码。imgedge_mask()line_sizeblur_value
  • 生成的边缘遮罩使用该函数保存为名为“pencil_sketch.jpg”的新图像文件。cv2.imwrite()
  • 然后使用该函数显示铅笔素描图像。cv2.imshow()
  • 程序等待使用该函数的用户按键。cv2.waitKey(0)
  • 最后,使用该功能关闭所有打开的窗口。cv2.destroyAllWindows()

4.2 从图像生成卡通:

total_color = 9
img = color_quantization(img, total_color)
cv2.imwrite('cartoonize.jpg', img)
cv2.imshow('Cartoonize', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

卡通化图片

4.3 代码说明:

  • 代码首先将值设置为 9。如果值发生变化,则生成的卡通图像将受到影响。较小的 值将导致较少的颜色,而较大的值将导致更多的颜色,这可能会影响卡通图像的整体外观。total_colortotal_colortotal_color
  • 调用该函数以将输入图像中的颜色数减少到指定的 。color_quantization()imgtotal_color
  • 生成的图像被保存为一个名为“cartoonize.jpg”的新图像文件使用该功能。cv2.imwrite()
  • 然后使用该功能显示卡通图像。cv2.imshow()
  • 程序等待使用该函数的用户按键。cv2.waitKey(0)
  • 最后,使用该功能关闭所有打开的窗口。cv2.destroyAllWindows()

五、对图像应用双边滤镜:

bilateral = cv2.bilateralFilter(img, 15, 75, 75)
# Save the output.
cv2.imwrite('blur.jpg', bilateral)
img = cv2.imread('blur.jpg')
cv2.imshow("Blur", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

双边滤波

5.1 代码说明:

  • 代码首先使用该函数将双边筛选器应用于输入图像。筛选器大小设置为 15,西格玛颜色和西格玛空间的值均设置为 75。imgcv2.bilateralFilter()
  • 更改双边滤镜的内核大小、西格玛颜色和西格玛空间的值将影响应用于图像的模糊级别。较小的内核大小和 sigma 值将导致较少的模糊,而较大的值将导致更多的模糊。更改这些值可能会更改生成的模糊图像的整体外观。
  • 生成的模糊图像被保存为一个名为“blur.jpg”的新图像文件,使用该功能。cv2.imwrite()
  • 然后使用该函数将模糊的图像加载回内存并分配给变量。cv2.imread()img

5.2 总输出:

5.3 另一种方式:

import cv2
import numpy as np# Load the input image
img = cv2.imread('input_image.jpg')# Apply bilateral filter to smooth the image
img_smooth = cv2.bilateralFilter(img, 9, 75, 75)# Convert the image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Apply edge detection to the grayscale image
edges = cv2.Canny(gray, 100, 200)# Apply color quantization to the smoothed image
img_quant = cv2.cvtColor(img_smooth, cv2.COLOR_BGR2RGB)
Z = img_quant.reshape((-1,3))
Z = np.float32(Z)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 8
ret,label,center=cv2.kmeans(Z,K,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)
center = np.uint8(center)
res = center[label.flatten()]
res2 = res.reshape((img_quant.shape))# Combine the edges and color quantization to create the cartoon effect
cartoon = cv2.bitwise_and(res2, res2, mask=edges)# Display the output image and save it
cv2.imshow('Cartoon', cartoon)
cv2.waitKey(0)
cv2.destroyAllWindows()

        总之,使用 OpenCV 将图像转换为卡通是一种有趣且创造性的方式,可以为您的照片赋予新的生命。在本文中,我们讨论了如何使用 OpenCV 通过应用各种图像处理技术(如颜色量化、边缘检测和双边过滤)将图像转换为卡通。通过结合这些技术,我们能够从普通照片中制作出风格化的卡通图像。

        虽然本文中提供的代码是一个很好的起点,但有很多方法可以自定义转换过程以获得不同的结果。尝试不同的参数值或应用其他图像处理技术有助于创建独特且个性化的卡通风格图像。有了一点创造力和一些图像处理技术的知识,可能性是无穷无尽的。

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

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

相关文章

Pytorch深度学习-----神经网络的基本骨架-nn.Module的使用

系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用(ToTensor,Normalize,Resize ,Co…

python爬虫基础入门——利用requests和BeautifulSoup

(本文是自己学习爬虫的一点笔记和感悟) 经过python的初步学习,对字符串、列表、字典、元祖、条件语句、循环语句……等概念应该已经有了整体印象,终于可以着手做一些小练习来巩固知识点,写爬虫练习再适合不过。 1. 网页基础 爬虫的本质就是从网页中获取所需的信息,对网…

类加载机制与类加载器

点击下方关注我,然后右上角点击...“设为星标”,就能第一时间收到更新推送啦~~~ Java 源码是如何形成类文件的,类文件又是如何加载到虚拟机的,类加载有哪些机制和原则呢?本文将为大家一一介绍。 1 Java 源码形成类文件…

基于拉格朗日-遗传算法的最优分布式能源DG选址与定容(Matlab代码实现)

目录 1 概述 2 数学模型 2.1 问题表述 2.2 DG的最佳位置和容量(解析法) 2.3 使用 GA 进行最佳功率因数确定和 DG 分配 3 仿真结果与讨论 3.1 33 节点测试配电系统的仿真 3.2 69 节点测试配电系统仿真 4 结论 1 概述 为了使系统网损达到最低值&a…

AI Chat 设计模式:10. 组合模式

本文是该系列的第八篇,采用问答式的方式展开,问题由我提出,答案由 Chat AI 作出,灰色背景的文字则主要是我的一些思考和补充。 问题列表 Q.1 给我介绍一下组合模式A.1Q.2 好的,给我举一个组合模式的例子,使…

idea导入maven项目问题

问题产生原因: ①idea加载maven项目,如果网络不通畅,会在maven仓库中产生一个文件,如下图所示: ②当网络通畅时,在下载就会因为此文件导致无法下载正确的maven依赖 解决方案: ①打开maven仓库的根目录 ②…

ts中声明引入未使用的报错——解决方案

在编写ts项目的时候,经常会出现如下报错: 导入声明中的所有导入都未使用 这是因为导入的模块暂时没有使用,ts给的一个提示信息 解决方案: 在ts.config.json中 把noUnusedLocals 设置为false即可 {"compilerOptions"…

【雕爷学编程】Arduino动手做(175)---机智云ESP8266开发板模块4

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&am…

【UE5 多人联机教程】03-创建游戏

效果 步骤 打开“UMG_MainMenu”,增加创建房间按钮的点击事件 添加如下节点 其中,“FUNL Fast Create Widget”是插件自带的函数节点,内容如下: “创建会话”节点指游戏成功创建一个会话后,游戏的其他实例即可发现&am…

微服务体系<1>

我们的微服务架构 我们的微服务架构和单体架构的区别 什么是微服务架构 微服务就是吧我们传统的单体服务分成 订单模块 库存模块 账户模块单体模块 是本地调用 从订单模块 调用到库存模块 再到账户模块 这三个模块都是调用的同一个数据库 这就是我们的单体架构微服务 就是…

Training-Time-Friendly Network for Real-Time Object Detection 论文学习

1. 解决了什么问题? 目前的目标检测器很少能做到快速训练、快速推理,并同时保持准确率。直觉上,推理越快的检测器应该训练也很快,但大多数的实时检测器反而需要更长的训练时间。准确率高的检测器大致可分为两类:推理时…

银河麒麟安装mysql数据库(mariadb)-银河麒麟安装JDK-银河麒麟安装nginx(附安装包)

银河麒麟离线全套安装教程(手把手教程) 1.银河麒麟服务器系统安装mysql数据库(mariadb) 2.银河麒麟桌面系统安装mysql数据库(mariadb) 3.银河麒麟服务器系统安装JDK 4.银河麒麟桌面系统安装JDK 5.银河麒麟…

青大数据结构【2021】

一、单选(17!) 根据中序遍历得到降序序列可以知道,每个结点的左子树的结点的值比该结点的值小,因为没有重复的关键字,所以拥有最大值的结点没有左子树。 二、简答 三、分析计算 四、算法分析 3.迪杰斯特拉…

windows安装Elasticsearch8.9.0

官网解压安装好路径(非中文,无空格) 可参考 言之有李LAX csdn http://t.csdn.cn/S2oju本人使用jdk17 修改配置elasticsearch.yml xpack.security.enabled: false xpack.security.http.ssl:enabled: false直接点击bin\elasticsearch.bat…

Unity 工具之 NuGetForUnity 包管理器,方便在 Unity 中的进行包管理的简单使用

Unity 工具之 NuGetForUnity 包管理器,方便在 Unity 中的进行包管理的简单使用 目录 Unity 工具之 NuGetForUnity 包管理器,方便在 Unity 中的进行包管理的简单使用 一、简单介绍 二、NuGetForUnity 的下载导入 Unity 三、NuGetForUnity 在 Unity 的…

LeetCode 75 第十二题(11)盛最多水的容器

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 配合着示例给出的图片我们可以得知找出盛水最多的容器是什么意思,给一个数组,找出数组中两个元素能围成的最大的矩阵面积是多少. 比较直观的想法是套两层for循环暴力解出来,但是这题是中等难度题,一般中等题是没法用暴力得…

pinia在vue3中的使用

总结: 在store文件夹中建一个pinia的文件userStore.js 1.要想使用pinia必须先引入defineStore 这里我们使用es6的模块化语法导出的 import { defineStore } from pinia 2.然后使用export const useUserStore defineStore(user,{}) defineStore 方法有两个参数&…

论文分享:PowerTCP: Pushing the Performance Limits of Datacenter Networks

1 原论文的题目(中英文)、题目中包含了哪些关键词?这些关键词的相关知识分别是什么? 题目:PowerTCP: Pushing the Performance Limits of Datacenter Networks PowerTCP:逼近数据中心的网络性能极限 2 论…

vue+Element项目中v-for循环+表单验证

如果在Form 表单里有通过v-for动态生成&#xff0c;如何设置验证呢&#xff1f; <el-form ref"ruleFormRef" :model"ruleForm" status-icon :rules"rules" label-width"120px"class"demo-ruleForm" hide-required-aster…

在EF Core中为数据表按列加密存储

假设有User表 public class User : Entity<int> {public int Id { get; set; }public string UserName { get; set; }public string Name { get; set; }public string IdentificationNumber { get; set; } }其中有身份证号码IdentificationNumber列&#xff0c;需要加密…