前言

在Android音视频开发中,网上知识点过于琐细,自学起来难度非常大,不过音视频大牛Jhuster提出了《Android 音视频从入门到提高 – 任务列表》,结合我自己的工作学习经历,我预备写一个音视频系列blog。本文是音视频系列blog的其中一个, 对应的要学习的内容是:运用OpenCV完成图片加载,图片腐蚀,图片含糊,图片边际检测,图片保存。


音视频系列blog

音视频系列blog: 点击此处跳转检查


目录

OpenCV基础(一):图片加载,图片腐蚀,图片模糊,图片边缘检测,图片保存


1.1 作用展示

话不多说,先上作用图!(源代码在文章最终)

加载图片:

OpenCV基础(一):图片加载,图片腐蚀,图片模糊,图片边缘检测,图片保存

图片腐蚀:

OpenCV基础(一):图片加载,图片腐蚀,图片模糊,图片边缘检测,图片保存

图片含糊:

OpenCV基础(一):图片加载,图片腐蚀,图片模糊,图片边缘检测,图片保存

图片边际检测:

OpenCV基础(一):图片加载,图片腐蚀,图片模糊,图片边缘检测,图片保存


1.2 图片加载

VS2017(或者其他版本VS)如何导入OpenCV,假如你不清楚,能够参考我的这篇文章:

OpenCV剖析tfboys十周年演唱会灯牌大战成果

图片加载代码如下:

#include <opencv2/opencv.hpp>
#include <iostream>
// 加载图片
int main() {
	// 界说图片文件的完整途径
	std::string image_path = "D:\\path_to_your_image.jpg";
	// 运用OpenCV加载图片
	cv::Mat image = cv::imread(image_path);
	if (image.empty()) {
		std::cerr << "Error: Unable to load image." << std::endl;
		return -1;
	}
	cv::imshow("Loaded Image", image);
	cv::waitKey(0);
	return 0;
}

Mat

在OpenCV中,cv::Mat 是一个非常重要的类,用于表明图画和矩阵数据,类似于Java中的 BufferedImage 类。它是OpenCV库中的核心数据结构之一,用于存储图画、矩阵和多维数组数据。cv::Mat 能够被看作是一个”容器”,用来存储图画和矩阵数据,就像一个盒子,能够放入各种东西。

imread

imread 是 OpenCV 库中的一个函数,用于读取图画文件并将其加载到 cv::Mat 方针中。详细来说,imread 用于从磁盘上的图画文件读取像素数据,并将这些像素数据存储在 cv::Mat 中,以便后续的图画处理和剖析。

在以下代码中:

cv::Mat image = cv::imread(image_path);

imread 将指定途径的图画文件加载到名为 imagecv::Mat 方针中。加载后,能够运用 image 方针进行图画处理操作。

imshow

imshow 也是 OpenCV 库中的一个函数,它用于显现图画在图形用户界面 (GUI) 窗口中,它答应你将图画在运用程序中的窗口中显现出来,以便用户能够看到图画的内容。

通常情况下,你能够将 cv::Mat 方针(包括加载的图画数据)传递给 imshow 函数,然后指定窗口的称号。例如:

cv::imshow("Loaded Image", image);

在这个示例中,"Loaded Image" 是窗口的称号,image 是包括图画数据的 cv::Mat 方针。当你调用 imshow 时,它将创立一个名为 "Loaded Image" 的窗口,并在该窗口中显现 image 中的图画数据。

waitKey(0)

cv::waitKey(0) 是 OpenCV 中的一个函数调用,它用于等候用户在图形用户界面 (GUI) 窗口中按下一个键。详细来说,这个函数在窗口上等候用户的键盘输入,并回来用户按下的键的ASCII码值。

在参数中的 0 表明函数将一直等候用户按键,直到用户按下键盘上的任意键。假如你将参数设置为一个正整数,例如 cv::waitKey(100),它将等候100毫秒,然后回来。假如用户在这个时间内按下了某个键,它将回来该键的ASCII码值;假如用户没有按下任何键,它将回来零。

通常,cv::waitKeycv::imshow 一起运用,以便在显现图画时能够等候用户的交互。例如:

cv::imshow("Loaded Image", image);
int key = cv::waitKey(0);
if (key == 27) {
    // 假如用户按下ESC键 (ASCII码值为27),则履行某些操作
    // 比如封闭窗口。。。
}

在这个示例中,cv::waitKey 用于等候用户在显现图画窗口中按下任意键,并将按下的键的ASCII码值存储在变量 key 中。然后,您能够依据用户的输入履行不同的操作,例如依据按下的键来决议封闭窗口或履行其他处理。


1.3 图片腐蚀

要在OpenCV中对图画进行腐蚀操作,能够运用 cv::erode 函数。腐蚀是一种形状学操作,通常用于图画处理中的图画细化、去噪等任务。下面是一个示例,演示如安在OpenCV中履行图片腐蚀操作:

#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
	// 读取图画
	cv::Mat image = cv::imread("D:\\path_to_your_image.jpg");
	if (image.empty()) {
		std::cerr << "Error: Unable to load image." << std::endl;
		return -1;
	}
	// 创立一个核(用于界说腐蚀的形状和巨细)
	cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));
	// 用来寄存腐蚀之后的图片
	cv::Mat erodedImage;
	// 履行腐蚀操作
	cv::erode(image, erodedImage, kernel);
	// 显现原始图画和腐蚀后的图画
	cv::imshow("原始图画", image);
	cv::imshow("腐蚀后的图画", erodedImage);
	// 等候用户按下键盘上的任意键
	cv::waitKey(0);
	return 0;
}

在这个示例中,咱们首先读取了一张图画,然后创立了一个核(cv::Mat kernel)来界说腐蚀操作的形状和巨细。能够依据需求调整核的巨细和形状。 (这个核,包括下面的出现的两种核,假如不明白也不要紧,我后面图画形状学会详细解说,你现在能够把这个核理解为一个工具,这个工具对每一个像素点进行相关操作,改动这个像素的数值,到达腐蚀,含糊等作用)

接下来,运用 cv::erode 函数来履行腐蚀操作,将原始图画 image 和核运用于腐蚀操作,成果存储在 erodedImage 中。

最终,咱们运用 cv::imshow 来显现原始图画和腐蚀后的图画,然后运用 cv::waitKey 等候用户按下键盘上的任意键,以便检查成果。

cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));

这行代码创立了一个核(Kernel)用于形状学操作,特别是腐蚀操作。这行代码的意义:

  1. cv::MORPH_RECT:这是核的形状,表明矩形形状的核。形状学操作通常运用不同形状的核,例如矩形、椭圆或交叉形。在这里,咱们选择了一个矩形形状的核,它将运用于腐蚀操作。
  2. cv::Size(5, 5):这是核的巨细,表明核的宽度和高度。在这个示例中,咱们创立了一个5×5巨细的核,它是一个5列5行的矩阵,用于界说腐蚀的操作范围。核的巨细会影响腐蚀的作用,较大的核会导致更激烈的腐蚀。

总归,这行代码创立了一个5×5巨细的矩形核,它将用于履行腐蚀操作。腐蚀操作会在图画中移动这个核,将核与图画中的像素进行比较,并将核下的像素值设置为核中一切像素的最小值,然后导致图画中的边际变细。核的巨细和形状能够依据详细的运用和图画处理需求进行调整。 ​

cv::erode(image, erodedImage, kernel);

这行代码运用了OpenCV的 cv::erode 函数来履行腐蚀操作。这行代码的意义:

  • image:这是输入图画,即你希望对其履行腐蚀操作的图画。在这个示例中,image 包括了加载的原始图画数据。
  • erodedImage:这是输出图画,即腐蚀操作的成果将存储在 erodedImage 中。cv::erode 函数将对输入图画 image 履行腐蚀操作,并将成果存储在 erodedImage 中。
  • kernel:这是从前创立的核(Kernel),它界说了腐蚀操作的形状和巨细。腐蚀操作将运用这个核在输入图画上移动,将核下的像素值设置为核中一切像素的最小值,然后履行腐蚀。

1.4 图片含糊

要在OpenCV中对图画进行含糊操作,能够运用 cv::GaussianBlur 函数来履行高斯含糊。高斯含糊是一种常用的图画含糊方法,能够用于下降图画中的噪声或滑润图画。以下是一个示例代码,演示如安在OpenCV中履行高斯含糊:

#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
    // 读取图画
    cv::Mat image = cv::imread("D:\\path_to_your_image.jpg");
    if (image.empty()) {
        std::cerr << "Error: Unable to load image." << std::endl;
        return -1;
    }
    // 界说含糊核的巨细
    cv::Size kernelSize(5, 5); // 能够依据需求调整核的巨细
    // 用来寄存含糊之后的图片
    cv::Mat blurredImage;
    // 履行高斯含糊操作
    cv::GaussianBlur(image, blurredImage, kernelSize, 0);
    // 显现原始图画和含糊后的图画
    cv::imshow("Original Image", image);
    cv::imshow("Blurred Image", blurredImage);
    // 等候用户按下键盘上的任意键
    cv::waitKey(0);
    return 0;
}

在这个示例中,首先读取了一张图画,然后界说了含糊核的巨细(kernelSize)。

接下来,运用 cv::GaussianBlur 函数来履行高斯含糊操作,将原始图画 image 和含糊核运用于图画,成果存储在 blurredImage 中。

最终,咱们运用 cv::imshow 来显现原始图画和含糊后的图画,并运用 cv::waitKey 等候用户按下键盘上的任意键,以便检查成果。

cv::Size kernelSize(5, 5);

cv::Size(5, 5) 是一个创立 OpenCV cv::Size 方针的语句,它用于指定含糊核的巨细。它的意义:

  • cv::Size 是 OpenCV 中的一个类,用于表明巨细或尺度。它通常用于指定矩形、核、图画等的巨细。
  • (5, 5) 是一个包括两个整数的元组,表明宽度和高度。在这个示例中,(5, 5) 表明含糊核的宽度为5个像素,高度为5个像素,因此含糊核是一个5×5的矩形。

所以,cv::Size(5, 5) 的意义是创立一个巨细为5×5的矩形核,该核将用于履行高斯含糊操作。核的巨细会影响含糊的程度,较大的核会导致更激烈的含糊作用,而较小的核会发生更细微的含糊作用。

高斯含糊是一种图画处理技术,用于下降图画中的噪声或滑润图画。它的首要原理是将图画中的每个像素点替换为其周围像素的加权平均值,其中权重是依据高斯分布来确认的。这意味着位于核中心的像素具有更大的权重,而离核中心越远的像素具有较小的权重。

高斯含糊的过程如下:

  1. 界说核的巨细: 首先,需求界说一个含糊核,它是一个矩形或正方形的区域,巨细由你自己指定。这个核的巨细决议了含糊的程度。
  2. 遍历图画: 对于图画中的每个像素,将含糊核放置在该像素周围的区域。
  3. 核算加权平均值: 核算核内一切像素的加权平均值。核中心的像素具有最高的权重,而离中心越远的像素权重越低。
  4. 替换像素值: 运用核算出的平均值替换原始像素的值。这个操作对图画中的每个像素都会履行,然后发生含糊后的图画。

高斯含糊的首要作用是下降图画中的噪声,滑润细节,并含糊图画的轮廓。含糊核的巨细决议了含糊的程度,较大的核会导致更激烈的含糊作用,而较小的核会发生较细微的含糊作用。

cv::GaussianBlur(image, blurredImage, kernelSize, 0);

cv::GaussianBlur 是 OpenCV 中用于履行高斯含糊操作的函数。

  • image:这是输入图画,即要对其履行高斯含糊操作的图画。在这个示例中,image 包括了加载的原始图画数据。
  • blurredImage:这是输出图画,即高斯含糊操作的成果将存储在 blurredImage 中。cv::GaussianBlur 函数将对输入图画 image 履行高斯含糊操作,并将成果存储在 blurredImage 中。
  • kernelSize:这是一个 cv::Size 方针,表明高斯核的巨细。在之前的代码中界说了 kernelSize,它决议了高斯含糊的程度,即核的巨细。在这个示例中,kernelSize 是一个5×5的巨细,用于界说高斯核的巨细。
  • 0:这是高斯含糊的标准差(standard deviation),通常为零。标准差用于确认高斯分布的形状,它能够影响含糊的程度。在这里,将标准差设置为零表明运用默认值,而不自界说高斯分布的形状。

1.5 图片边际检测

要在OpenCV中对图画进行边际检测,能够运用一种称为Canny边际检测的算法。以下是一个示例代码,演示如安在OpenCV中履行Canny边际检测:

#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
	// 读取图画
	cv::Mat image = cv::imread("D:\\path_to_your_image.jpg");
	if (image.empty()) {
		std::cerr << "Error: Unable to load image." << std::endl;
		return -1;
	}
	// 用来寄存边际检测之后的图片
	cv::Mat edges;
	// 履行Canny边际检测
	cv::Canny(image, edges, 100, 200); // 调整阈值以操控边际检测的灵敏度
	// 显现原始图画和边际检测成果
	cv::imshow("Original Image", image);
	cv::imshow("Edges", edges);
	// 等候用户按下键盘上的任意键
	cv::waitKey(0);
	return 0;
}

在这个示例中,咱们首先读取了一张图画。然后,咱们运用 cv::Canny 函数来履行Canny边际检测,将输入图画 image 和一些参数传递给它。在这里,参数 100200 别离表明低阈值和高阈值。能够依据需求调整这些阈值以操控边际检测的灵敏度。

最终,咱们运用 cv::imshow 来显现原始图画和边际检测的成果,并运用 cv::waitKey 等候用户按下键盘上的任意键,以便检查成果。

cv::Canny(image, edges, 100, 200);

cv::Canny 是 OpenCV 中用于履行Canny边际检测的函数。

  • image:这是输入图画,即要对其履行Canny边际检测的图画。在这个示例中,image 包括了你加载的原始图画数据。请注意,Canny边际检测通常用于灰度图画,因此在运用前,您可能需求将图画转换为灰度图画。

  • edges:这是输出图画,Canny边际检测的成果将存储在 edges 中。cv::Canny 函数将检测到的边际信息存储在这个图画中。

  • 100200:这是两个阈值参数。这两个阈值参数用于操控边际检测的灵敏度和边际连接的强度。

    • 100 是低阈值(Low threshold):低于这个阈值的边际被丢掉(便是图片黑色部分)。
    • 200 是高阈值(High threshold):高于这个阈值的像素被认为是强边际(便是图片白色部分)。

通过调整这两个阈值参数,能够操控Canny边际检测的成果,以习惯不同的图画和运用场景。较低的阈值会导致更多的边际被检测到,而较高的阈值会发生更强的边际。能够依据你的需求和图画特性来调整这些阈值。


1.6 图片保存

以下是一个示例代码,演示如安在OpenCV中对一张彩色图画履行Canny边际检测,并将成果保存到D盘:

#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
    // 读取彩色图画
    cv::Mat image = cv::imread("D:\\path_to_your_image.jpg");
    if (image.empty()) {
        std::cerr << "Error: Unable to load image." << std::endl;
        return -1;
    }
    // 用来寄存边际检测之后的图片
    cv::Mat edges;
    // 履行Canny边际检测
    cv::Canny(image, edges, 100, 200); // 调整阈值以操控边际检测的灵敏度
    // 保存边际检测成果到D盘
    cv::imwrite("D:\\edges.jpg", edges);
    std::cout << "Edges saved to D:\\edges.jpg" << std::endl;
    return 0;
}

在这个示例中,咱们首先读取了一张彩色图画,然后运用 cv::Canny 函数履行Canny边际检测,将输入图画 image 作为输入,并将边际检测成果存储在 edges 中。

接下来,咱们运用 cv::imwrite 函数将边际检测成果保存为一张新的图画文件,存储在D盘的根目录下,文件名为 “edges.jpg”。您能够依据需求更改保存途径和文件名。

cv::imwrite(“D:\edges.jpg”, edges);

cv::imwrite 是 OpenCV 中用于将图画保存为文件的函数。

  • "D:\\edges.jpg":这是保存图画的方针文件途径。在这里,图画将保存为名为 “edges.jpg” 的文件,该文件将存储在D盘(D:\)的根目录下。能够依据需求更改方针文件的途径和文件名。
  • edges:这是要保存的图画数据。在这个示例中,edges 包括了之前履行Canny边际检测操作后得到的边际图画数据。cv::imwrite 将这个图画数据保存为指定途径的图画文件。

源代码:(欢迎star)
OpenCV根底(一):图片加载,图片腐蚀,图片含糊,图片边际检测,图片保存