【python】OpenCV—Cartoonify and Portray

在这里插入图片描述

参考来自

  • 使用Python+OpenCV将照片变成卡通照片

文章目录

  • 1 卡通化
    • code
    • cv2.medianBlur
    • cv2.adaptiveThreshold
    • cv2.kmeans
    • cv2.bilateralFilter
  • 2 肖像画
    • cv2.divide

1 卡通化

code

import cv2
import numpy as np


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_GAUSSIAN_C, cv2.THRESH_BINARY,
                                  line_size, blur_value,)
    return edges


def color_quantization(img, k):
    # transrorm the image
    data = np.float32(img).reshape((-1, 3))

    # determine criteria
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 0.001)

    # implementing k-means
    ret, 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


if __name__ == "__main__":
    img = cv2.imread('2.jpg')

    line_size = 3
    blur_value = 3
    edges = edge_mask(img, line_size, blur_value)
    cv2.imwrite("edges.jpg", edges)

    total_color = 3
    img_quan_color = color_quantization(img, total_color)
    cv2.imwrite("img_quan_color.jpg", img_quan_color)

    blurred = cv2.bilateralFilter(img_quan_color, d=3, sigmaColor=200, sigmaSpace=200)
    cartton = cv2.bitwise_and(blurred, blurred, mask=edges)
    cv2.imwrite("cartton.jpg", cartton)

    # cv2.imshow("1", cartton)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()

输入图片

在这里插入图片描述
边缘
在这里插入图片描述
颜色量化
在这里插入图片描述

边缘和颜色量化合并

在这里插入图片描述


下面消融下一些细节配置

line_size 设置为 3~15

在这里插入图片描述


line_size = 3
blur_value 设置为 3~15
在这里插入图片描述


颜色量化

total_color = 3~15

在这里插入图片描述
在这里插入图片描述
越大颜色越丰富


双边滤波

d=3~15

在这里插入图片描述

cv2.medianBlur

该函数用于对图像进行中值滤波,主要用于消除图像中的椒盐噪声和脉冲噪声。它通过取邻域内所有像素值的中值来替代当前像素点的像素值,能够有效保护图像边缘信息,避免线性滤波器可能带来的图像细节模糊。

1)函数原型

dst = cv2.medianBlur(src, ksize)

2)参数说明

src:需要处理的图像,即源图像。图像可以具有任意数量的通道,这些通道可以独立处理。图像深度应为 CV_8U、CV_16U、CV_16S、CV_32F 或 CV_64F 中的一个。

ksize:滤波核的大小。滤波核大小是指在滤波处理过程中其邻域图像的高度和宽度。核大小必须是比 1 大的奇数,例如 3、5、7 等。

3)返回值

dst:进行中值滤波后得到的处理结果,与源图像 src 的尺寸和类型相同。

4)使用注意事项

在进行滤波时,应注意 ksize 参数的选择。过小的 ksize 可能无法有效去除噪声,而过大的 ksize 则可能导致图像细节损失。

由于中值滤波是非线性的,它可能无法处理一些非线性噪声。

中值滤波对于去除椒盐噪声和脉冲噪声特别有效,但对于其他类型的噪声可能效果有限。

cv2.adaptiveThreshold

该函数用于对图像进行自适应阈值处理,即根据图像的局部区域来计算阈值,并应用这个阈值对图像进行二值化。这种处理方式特别适用于光照不均匀的图像。

1)函数原型

dst = cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)

2)参数说明

src:输入图像,必须是单通道图像(灰度图像)。

maxValue:阈值化后的最大值。当满足条件时,像素值将被设置为 maxValue,否则为 0。

adaptiveMethod:自适应阈值算法的选择。

  • cv2.ADAPTIVE_THRESH_MEAN_C:使用相邻区域的平均值减去常数 C 作为阈值。
  • cv2.ADAPTIVE_THRESH_GAUSSIAN_C:使用相邻区域的加权和(高斯加权)减去常数 C 作为阈值。

thresholdType:二值化类型。

  • cv2.THRESH_BINARY:大于阈值的像素值设置为 maxValue,小于等于阈值的像素值设置为 0。
  • cv2.THRESH_BINARY_INV:与 cv2.THRESH_BINARY 相反。

blockSize:用于计算阈值的邻域大小(必须是正奇数)。例如,3、5、7 等。

C:从计算出的阈值中减去的常数,通常为正数。

3)返回值

dst:自适应阈值处理后的输出图像,与输入图像 src 的尺寸相同,但类型为二值图像。

4)注意事项

自适应阈值处理可以有效地处理光照不均匀的图像,因为它会根据每个像素的局部邻域来动态计算阈值。

blockSize 参数决定了计算阈值时考虑的邻域大小,可以根据图像的具体情况选择。

C 参数用于调整最终的阈值,可以根据需要进行调整。

cv2.kmeans

该函数用于执行 K-Means 聚类算法,将输入数据划分为 K 个集群,并返回每个数据点的集群标签和集群的质心。

1)函数原型
retval, labels, centers = cv2.kmeans(data, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)

2)参数说明

data:输入数据,通常是 NumPy 数组,其形状为 (N, M),其中 N 是数据点的数量,M 是每个数据点的维数。

K:需要划分的集群数量。

termCriteria:终止条件,通常是一个元组,包含三个参数 (type, maxIter, epsilon)。其中 type 可以是 cv2.TERM_CRITERIA_EPS、cv2.TERM_CRITERIA_MAX_ITER 或它们的组合(使用按位或运算符 | 连接),maxIter 是最大迭代次数,epsilon 是收敛的精度要求。

attempts:算法尝试的次数。算法使用不同的初始标签集进行多次运行,并返回最佳结果。这个参数指定了尝试的次数。

flags:初始化质心的方法。目前唯一可用的标志是 cv2.KMEANS_RANDOM_CENTERS,它使用随机值初始化质心。

centers(可选):用于传递预定义的质心数组。如果不提供,则会根据 flags 参数随机初始化质心。

3)返回值

retval:迭代次数。算法执行的实际迭代次数。

labels:每个数据点的集群标签。形状为 (N,) 的 NumPy 数组,其中 N 是数据点的数量。

centers:集群的质心。形状为 (K, M) 的 NumPy 数组,其中 K 是集群的数量,M 是数据点的维数。

4)使用注意事项

在使用 K-Means 算法时,选择合适的 K 值非常重要。K 值过小可能无法充分描述数据的分布,而 K 值过大可能导致过拟合。

由于 K-Means 算法是随机的,每次运行的结果可能略有不同。为了获得更稳定的结果,可以多次运行算法并取平均结果。

数据的预处理(如缩放、归一化)对 K-Means 算法的性能和结果有重要影响。确保在输入数据之前进行适当的预处理。

cv2.bilateralFilter

该函数使用双边滤波算法对图像进行平滑处理,去除噪声的同时保留边缘信息。

1)函数原型

dst = cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])

2)参数说明

src:输入图像,应为8位或浮点型、1通道或3通道图像。

d:滤波时考虑的像素直径(不是半径)。对于较大的值,该滤波器将不会有太大差异,但会增加计算时间。它可以是大于1的整数,但通常建议使用不超过15的值。

sigmaColor:颜色空间的标准差。一个较大的值意味着像素邻域内有较大颜色变化的像素能够影响到滤波器的中心像素。这有助于在平滑图像时保留边缘。

sigmaSpace:坐标空间的标准差(以像素为单位)。如果参数值较大,那么只有在像素坐标空间中距离足够近的像素才会影响中心像素的值。这有助于在平滑图像时保留边缘。

dst(可选):输出图像,与源图像具有相同的尺寸和类型。

borderType(可选):像素外推法,决定如何处理边界像素。默认值为 cv2.BORDER_DEFAULT。

3)返回值

dst:滤波后的图像,与源图像具有相同的尺寸和类型。

4)使用注意事项

d 参数的选择:虽然较大的值可能不会显著改变滤波器的效果,但会增加计算时间。因此,在实际应用中,通常建议使用较小的值(如15或更小)。

sigmaColor 和 sigmaSpace 的选择:这两个参数共同决定了双边滤波器的行为。较大的 sigmaColor 值允许颜色变化较大的像素影响中心像素,而较大的 sigmaSpace 值则限制了仅在空间距离较近的像素才能影响中心像素。根据具体的应用场景,可能需要调整这两个参数的值以达到最佳效果。

边缘保留:与其他线性滤波方法(如高斯滤波)相比,双边滤波能够在平滑图像的同时更好地保留边缘信息。这是因为双边滤波在考虑像素之间的空间距离之外,还考虑了像素之间的灰度值相似性。

2 肖像画

import cv2

import os
# print(os.listdir("../../datasets/human_Wild_public/images/mpii_029329465.jpg"))
img = cv2.imread("C://Users/Administrator/Desktop/1.jpeg")

gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
invert_g_i = 255 - gray_img

blurred_i_g_i = cv2.GaussianBlur(invert_g_i, (19, 19), 0)

invert = 255 - blurred_i_g_i

sketck = cv2.divide(gray_img, invert, scale=256.0)
cv2.imwrite("C://Users/Administrator/Desktop/2.jpeg", sketck)

# cv2.imshow("ori", img)
# cv2.imshow("pencil sketch", sketck)
# cv2.waitKey(0)

原图
请添加图片描述
灰度图
请添加图片描述
反向灰度图
请添加图片描述
求模糊
请添加图片描述
反回来
请添加图片描述
肖像画
请添加图片描述

cv2.divide

执行两个数组(图像)的逐元素相除操作。

1)函数原型

dst = cv2.divide(src1, src2[, dst[, scale[, dtype[, mask]]]])

2)参数说明

src1:第一个输入数组(通常是图像)。

src2:第二个输入数组(通常是图像),其元素将用作除数。

dst(可选):输出数组,与 src1 具有相同的尺寸和通道数。

scale(可选):可选的缩放因子。如果指定了,则结果将乘以这个值。默认值为 1。

dtype(可选):输出数组的可选深度。默认与输入数组的深度相同。

mask(可选):可选的 8 位单通道数组,用于指定哪些元素需要参与计算。

3)返回值

dst:输出数组,包含 src1 数组的元素与 src2 数组的元素相除的结果(如果提供了 scale,则乘以 scale)。

4)使用注意事项

如果 src2 中的任何元素为零,则结果将是未定义的(在浮点数中可能是 NaN 或无穷大)。因此,在使用 cv2.divide 之前,确保 src2 中没有零元素,或者准备处理可能出现的异常情况。

mask 参数允许你选择性地执行逐元素除法,只影响那些 mask 中对应位置为真的元素。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第二证券炒股技巧:科创板和创业板参与门槛一样吗?

科创板和创业板参加门槛是不相同的。 科创板注册条件:申请注册权限前20个生意日证券及资金账户日均财物不低于50万元,不包括融资融券融入的资金与证券,两年及以上的股票生意经历,风险承受才能C4及以上。 创业板注册条件&#xf…

Redux 与 MVI:Android 应用的对比

Redux 与 MVI:Android 应用的对比 在为 Android 应用选择合适的状态管理架构时可能会感到困惑。在这个领域中,有两种流行的选择是 Redux 和 MVI(Model-View-Intent)。两者都有各自的优缺点,因此在深入研究之前了解它们…

【YOLO系列】YOLOv1学习(PyTorch)原理加代码

论文网址:https://arxiv.org/pdf/1506.02640 训练集博客链接:目标检测实战篇1——数据集介绍(PASCAL VOC,MS COCO)-CSDN博客 代码文件:在我资源里,但是好像还在审核,大家可以先可以,如果没有的…

Hadoop3:MapReduce源码解读之Map阶段的FileInputFormat的切片原理(2)

Job那块的断点代码截图省略,直接进入切片逻辑 参考:Hadoop3:MapReduce源码解读之Map阶段的Job任务提交流程(1) 4、FileInputFormat切片源码解析 切片入口 获取切片 获取切片最大的Size和切片最小的Size 判断文件是…

[Shell编程学习路线]——编制第一个shell脚本入门篇

🏡作者主页:点击! 🛠️Shell编程专栏:点击! ⏰️创作时间:2024年6月12日10点23分 🀄️文章质量:93分 目录 ——前言—— 💥常用的几种shell Bash Sh …

ip地址的表示方式有哪几种

在当今数字化、网络化的时代,IP地址已成为我们生活中不可或缺的一部分。无论是浏览网页、在线购物,还是远程办公、视频会议,IP地址都在背后默默发挥着作用。IP地址是互联网协议地址的简称,它为每一个连接到互联网的设备提供了一个…

antdv 下拉框增加全选功能

由于select下拉框中内容过多&#xff0c;使用下拉框多选需要一个一个选取太过于麻烦&#xff0c;所以在下拉中增加全选和取消全选操作。 看官方文档发现&#xff0c;dropdownRender 可以自定义下拉框内容&#xff0c;可以满足我们的需要。 代码实现 <a-select mode"…

5款非常好用的小众软件,你值得拥有

​ 今天为大家推荐五款不常见但好用的win10软件&#xff0c;它们都有着各自的特色和优势&#xff0c;相信你会喜欢的。 1. 文件夹查看——Folder Size View ​ Folder Size View是一款高效的文件夹大小查看工具&#xff0c;它能够快速扫描并展示文件夹及其子文件夹的占用空间…

力扣42 接雨水

听说字节每人都会接雨水&#xff0c;我也要会哈哈哈 数据结构&#xff1a;数组 算法&#xff1a;核心是计算这一列接到多少雨水&#xff0c;它取决于它左边的最大值和右边的最大值&#xff0c;如下图第三根柱子能接到的雨水应该是第一根柱子高度和第五根柱子高度的最小值减去第…

光学知识 | 什么是超透镜,其工作原理是什么?

在复杂的成像和照明设备中&#xff0c;超透镜&#xff08;以及更普遍的超表面&#xff09;被越来越多地视为一种切实可行的解决方案&#xff0c;以用于提高系统性能&#xff0c;同时缩小系统尺寸并减轻重量。这是因为通常单个超透镜即可达到原本需要在设备中使用多个“传统”光…

带你走进信息安全软件架构

汽车行业网联化以及网络安全风险日益突出&#xff0c;汽车网络攻击&#xff0c;漏洞日益增加&#xff0c;危害防不胜防。汽车信息安全逐步受到重视&#xff0c;网络安全相关法律法规陆续颁布。在这样的背景下&#xff0c;AUTOSAR 组织也发布了有关信息安全模块和 Crypto Stack(…

对象和引用类型的赋值都是通过引用传递的方式进行的,这意味着变量实际上存储的是对象的引用,而不是对象本身的副本

这篇博客我主要想解释一下这句话&#xff1a;对象和引用类型的赋值都是通过引用传递的方式进行的&#xff0c;这意味着变量实际上存储的是对象的引用&#xff0c;而不是对象本身的副本。 其实这段话早在学习JS的时候就接触过&#xff0c;只是被我丢进了“记忆垃圾桶”&#xf…

【C++进阶】模板与仿函数:C++编程中的泛型与函数式编程思想

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;栈和队列相关知识 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀模板进阶 &#x1f9e9;<&…

Javascript学习之路:js中关于遍历总结

循环/遍历 循环&#xff0c;就是一遍又一遍的重复执行相同或者相似的代码循环结构的两个要素 循环体–要执行的相同或相似的语句循环条件–重复执行的次数&#xff0c;或者继续执行循环的条件 &#x1f449;while循环 while循环语法格式 while(boolean表达式){循环体语句}//…

数据库选型实践:如何避开分库分表痛点 | OceanBase用户实践

随着企业业务的不断发展&#xff0c;数据量往往呈现出快速的增长趋势。使用MySQL的用户面对这种增长&#xff0c;普遍选择采用分库分表技术作为应对方案。然而&#xff0c;这一方案常在后期会遇到很多痛点。 分库分表的痛点 痛点 1&#xff1a;难以保证数据一致性。由于分库分…

算法之分治

分而治之 分治法所能解决的问题一般具有以下几个特征&#xff1a; 1) 该问题的规模缩小到一定的程度就可以容易地解决 2) 该问题可以分解为若干个规模较小的子问题&#xff0c;即该问题具有最优子结构性质 3) 利用该问题分解出的子问题的解可以合并为该问题的解 4) 该问题所分…

Redis在互联网大厂中的应用案例分析

携程金融的Redis架构 携程金融在经过多年的演进后,形成了多层次的系统架构,其中基础数据(如用户信息、产品信息、订单信息等)由底层系统产生,并服务于所有的金融系统。这些基础数据通过统一的缓存服务(系统名utag)进行缓存。缓存数据具有全量、准实时、永久有效的特点,…

【SpringBoot + Vue 尚庭公寓实战】标签和配套管理接口实现接口实现(六)

【SpringBoot Vue 尚庭公寓实战】标签和配套管理接口实现接口实现&#xff08;六&#xff09; 文章目录 【SpringBoot Vue 尚庭公寓实战】标签和配套管理接口实现接口实现&#xff08;六&#xff09;1、保存或更新标签信息2、根据id删除标签信息3、根据类型查询配套列表4、新…

【机器学习】基于CNN-RNN模型的验证码图片识别

1. 引言 1.1. OCR技术研究的背景 1.1.1. OCR技术能够提升互联网体验 随着互联网应用的广泛普及&#xff0c;用户在日常操作中频繁遇到需要输入验证码的场景&#xff0c;无论是在登录、注册、支付还是其他敏感操作中&#xff0c;验证码都扮演着重要角色来确保安全性。然而&am…

OCC+VS+QT项目配置

1、安装好VS2022、QT、OCC安装包后&#xff0c;在VS2022中创建一个项目&#xff0c;具体如下&#xff1a; 2、配置步骤1中创建的项目的属性&#xff0c;具体如下&#xff1a; VC目录>>>包含目录&#xff1a; 添加文件目录如上三个。 VC目录>>>库目录&#xf…