20个基础到进阶版的OpenCV4.9.0趣味项目(C++版)(七)——图片素描化和卡通化

20个基础到进阶版的OpenCV4.9.0趣味项目(C++版)(七)——图片素描化和卡通化

一、引言

在图像处理领域,将图片转化为素描或卡通风格是一项既有趣又实用的技术。这种转换不仅增强了图像的视觉效果,还为艺术创作、教育演示、游戏开发以及电影特效制作等领域带来了无限可能。本文将详细介绍如何使用OpenCV库来实现图片的素描化和卡通化处理。
在这里插入图片描述

二、核心知识

1.中值滤波

中值滤波的基本原理是选取图像中某一个像素点的邻域窗口,将窗口内的所有像素点的灰度值(或颜色值)进行排序,然后取排序后的中间值作为该像素点滤波后的新值。这个过程可以消除孤立的噪声点,使像素值更加接近真实值,从而达到平滑去噪的目的。

具体步骤:
1)确定邻域窗口:
首先,需要确定一个邻域窗口的大小和形状,常用的窗口大小有3x3、5x5等,形状通常为正方形或矩形。窗口的大小和形状会影响滤波的效果,需要根据具体的应用场景和图像特性进行选择。
2)排序窗口内像素值:
将邻域窗口内的所有像素点的灰度值(或颜色值)进行排序。排序的方法可以是从小到大,也可以是从大到小,但结果是一致的,因为都是取中间值。
3)取中间值:
排序完成后,取排序后的中间值作为该像素点滤波后的新值。如果窗口内的像素点数为奇数,则中间值就是排序后位于中间的那个值;如果窗口内的像素点数为偶数,则中间值可以是排序后中间两个值的平均值,也可以是其他某种方式确定的值(但这种情况较少见,因为通常选择奇数大小的窗口以避免这种模糊性)。

未排序的点:
在这里插入图片描述
中值排序后的点:
在这里插入图片描述
特点与优势:
1)去除噪声:
中值滤波能够有效地去除图像中的椒盐噪声等脉冲噪声,因为这些噪声点通常是孤立的,排序后不会成为中间值。
2)保持边缘:
与均值滤波等线性滤波方法相比,中值滤波在去除噪声的同时能够更好地保持图像的边缘信息,因为边缘信息通常是由相邻像素间较大的灰度值差异形成的,这种差异在中值滤波过程中不会被平滑掉。
3)适应性强:
中值滤波的滤波效果与窗口大小和形状的选择密切相关,因此可以根据不同的应用场景和图像特性进行灵活调整,以达到最佳的滤波效果。

未滤波的图像:
在这里插入图片描述
中值滤波后的图像:
在这里插入图片描述

2.拉普拉斯边缘提取

在图像中,像素值的变化通常是不均匀的,而在边缘处,像素值的变化通常是最大的。拉普拉斯算子通过计算图像的二阶导数来检测这些变化点。在连续函数中,二阶导数的零点通常对应于一阶导数的极值点,这些极值点就是图像中的边缘。
在这里插入图片描述

3.阈值分割–反向二值化

在OpenCV中,阈值分割是一种用于图像二值化的技术,它将图像转换为仅包含两种像素值的图像(通常是0和255)。反向二值化(Inverse Binary Thresholding)是其中的一种方法,它通过设置阈值将高于该阈值的像素值设置为0,低于该阈值的像素值设置为255。
在这里插入图片描述

4.双边滤波

双边滤波结合了图像的空间邻近度和像素值相似度,同时考虑空域信息和灰度相似性,以达到保留边缘并去除噪声的目的。具体来说,双边滤波采用了两个高斯滤波的结合:
1)空间邻近度高斯滤波:负责计算像素之间的空间邻近度权值,即常用的高斯滤波器原理。
2)像素值相似度高斯滤波:负责计算像素值之间的相似度权值。
这两个高斯滤波的同时作用,构成了双边滤波。因此,双边滤波能够在滤除噪声、平滑图像的同时,较好地保留边缘信息。
在这里插入图片描述

三、代码演示

1.图片素描化

cv::Mat img = *(cv::Mat*)userdata;
if (img.empty())
{
	printf("载入图像为空!\r\n");
	return;
}

cv::Mat grayImg;
cv::cvtColor(img, grayImg, cv::COLOR_BGR2GRAY);

cv::Mat filtImg;
cv::medianBlur(grayImg, filtImg, 7);

cv::Mat eImg;
cv::Laplacian(filtImg, eImg, CV_8UC1, 5);

cv::Mat resImg;
cv::threshold(eImg, resImg, val, 255, cv::THRESH_BINARY_INV);

cv::imshow("Sketch", resImg);

在这里插入图片描述

2.图片卡通化

cv::Mat img = *(cv::Mat*)userdata;
if (img.empty())
{
	printf("载入图像为空!\r\n");
	return;
}

cv::Mat grayImg;
cv::cvtColor(img, grayImg, cv::COLOR_BGR2GRAY);

cv::Mat filtImg;
cv::medianBlur(grayImg, filtImg, 7);

cv::Mat eImg;
cv::Laplacian(filtImg, eImg, CV_8UC1, 5);

cv::Mat resImg;
cv::threshold(eImg, resImg, val, 255, cv::THRESH_BINARY_INV);

cv::Mat cal1 = img.clone();
cv::Mat cal2 = img.clone();
int iter = 3;
for (int i = 0; i < iter; ++i)
{
	int kernelSize = 9;
	double sigmaColor = 9;
	double sigmaSpace = 7;

	cv::bilateralFilter(cal1, cal2, kernelSize, sigmaColor, sigmaSpace);
	cv::bilateralFilter(cal2, cal1, kernelSize, sigmaColor, sigmaSpace);

}
cv::Mat dstImg;
dstImg.setTo(0);
cal1.copyTo(dstImg, resImg);

cv::imshow("Cartoon", dstImg);

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值