Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理

这篇具有很好参考价值的文章主要介绍了Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、概述图像滤波

头文件 quick_opencv.h:声明类与公共函数

#pragma once
#include <opencv2\opencv.hpp>
using namespace cv;

class QuickDemo {
public:
	...
	void blur_Demo(Mat& image);
	void medianblur_Demo(Mat& image);
	void gaussian_Demo(Mat& image);
	void bilateralFilter_Demo(Mat& image);

	void custom_mask_Demo(Mat& image); //自定义掩膜运算
    void edge_process_Demo(Mat& image1);

};

主函数调用

#include <opencv2\opencv.hpp>
#include <quick_opencv.h>
#include <iostream>
using namespace cv;


int main(int argc, char** argv) {
	Mat src = imread("D:\\Desktop\\pandas.jpg");
	if (src.empty()) {
		printf("Could not load images...\n");
		return -1;
	}
	namedWindow("input", WINDOW_NORMAL);
	imshow("input", src);

	QuickDemo qk;

	...
	qk.blur_Demo(src);
	qk.medianblur_Demo(src);
	qk.gaussian_Demo(src);
	qk.bilateralFilter_Demo(src);
	qk.custom_mask_Demo(src);
	qk.edge_process_Demo(src1);
	waitKey(0);
	destroyAllWindows();
	return 0;
}

1.1、均值滤波

blur( InputArray src,OutputArray dst, Size ksize, 
      Point anchor = Point(-1,-1)int borderType = BORDER_DEFAULT)

src:输入图像 。

dst:输出图像 。

ksize:内核大小 ,一般用 Size(w,h),w 为宽度,h 为深度。

anchor:被平滑的点,表示取 内核中心 ,默认值 Point(-1,-1)。

boderType:推断图像外部像素的某种边界模式。默认值 BORDER_DEFAULT

目的:去除图像上的尖锐噪声,平滑图像。 原理:均值滤波属于线性滤波,它的实现原理是邻域平均法
Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记
源文件 quick_demo.cpp:实现类与公共函数

void QuickDemo::blur_Demo(Mat& image) {
	Mat dst, dst1, dst2;
	blur(image, dst, Size(5, 5), Point(-1, -1));
	blur(image, dst1, Size(15, 1), Point(-1, -1));
	blur(image, dst2, Size(1, 15), Point(-1, -1));
	imshow("均值滤波", dst);
	imshow("横向滤波", dst1);
	imshow("竖直滤波", dst2);
}

Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记

1.2中值滤波

medianBlur(InputArray src,OutputArray dst,int ksize)

src:输入图像 。

dst:输出图像 。

ksize:孔径的线性尺寸,这个参数必须是大于1 的奇数

统计排序滤波器 中值对椒盐噪声有很好的抑制作用

void QuickDemo::medianblur_Demo(Mat& image) {
	Mat dst, dst1, dst2;
	medianBlur(image.clone(), dst, (3, 3));
	medianBlur(image.clone(), dst1, (5, 5));
	medianBlur(image.clone(), dst2, (7, 7));
	imshow("中值滤波", dst);
	imshow("中值滤波1", dst1);
	imshow("中值滤波2", dst2);
}

1.3、高斯滤波

GaussianBlur( InputArray src, OutputArray dst, Size ksize,
                   double sigmaX, double sigmaY = 0,
                   int borderType = BORDER_DEFAULT )

src:输入图像 。

dst:输出图像 。

ksize:ksize.width 和 ksize.height 可以不同,但他们都必须为正数和奇数,或者为0,可由 sigma 计算而来

sigmaX:高斯核函数在 X 方向的的标准差

sigmaY:高斯核函数在 Y 方向的的标准差

若 sigmaY 为零,就将它设为 sigmaX;若 sigmaX 和 sigmaY 都是0,那么就由 ksize.width 和 ksize.height 计算出来

高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。

高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。

高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。
Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记
Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记

void QuickDemo::gaussian_Demo(Mat& image) {
	Mat dst;
	GaussianBlur(image, dst, Size(5, 5), 15);
	imshow("高斯滤波", dst);
}

1.4、双边滤波

边缘保留滤波算法:

  • 高斯双边滤波
  • Meanshift均值迁移模糊
  • 局部均方差模糊
  • 导向滤波

双边滤波的原理示意图:
Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记

void bilateralFilter(
InputArray src,    输入图像
OutputArray dst,   目标图像,需要和源图片有一样的尺寸和类型
int d,        在过滤期间使用的每个像素邻域的直径。如果输入d非0(没输入),则sigmaSpace由d计算得出。
double sigmaColor,  颜色空间滤波器的sigma值,这个参数的值越大,就表明该像素邻域内有更宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
double sigmaSpace, 坐标空间滤波器的sigma值,坐标空间的标注方差。他的数值越大,意味着越远的像素会相互影响,从而使更大的区域足够相似的颜色获取相同的颜色。当d>0,d指定了邻域大小且与sigmaSpace无关。否则,d正比于sigmaSpace。
int borderType = BORDER_DEFAULT  图像边界模式
)

src: 输入图像,可以是Mat类型,图像必须是8位或浮点型单通道、三通道的图像。
dst: 输出图像,和原图像有相同的尺寸和类型。
d: 表示在过滤过程中每个像素邻域的直径范围。如果这个值是非正数,则函数会从第五个参数sigmaSpace计算该值。
sigmaColor:颜色空间过滤器的sigma值,这个参数的值月大,表明该像素邻域内有月宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
sigmaSpace: 坐标空间中滤波器的sigma值,如果该值较大,则意味着颜色相近的较远的像素将相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。当d>0时,d指定了邻域大小且与sigmaSpace五官,否则d正比于sigmaSpace.
borderType=BORDER_DEFAULT: 用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT.

void QuickDemo::bilateralFilter_Demo(Mat& image) {
	Mat dst;
	bilateralFilter(image, dst, 0, 100.0, 10.0);
	imshow("双边滤波", dst);
}

Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记

1.5、方框滤波

boxFilter( InputArray src, OutputArray dst, int ddepth,
                Size ksize, Point anchor = Point(-1,-1),
                bool normalize = true,
                int borderType = BORDER_DEFAULT )

src:输入图像

dst:输出图像

ddepth:输出图像的深度,-1 代表使用原图深度

ksize: 滤波内核的大小。一般这样写Size(w, h)来表示内核的大小,Size(10, 10)就表示 10x10 的核大小

anchor = Point(-1,-1) :表示锚点(即被平滑的那个点),注意他有默认值Point(-1,-1)
如果这个点坐标是负值的话,就表示取核的中心为锚点,所以默认值Point(-1,-1)表示这个锚点在核的中心。

normalize = true:默认值为true,一个标识符,表示内核是否被其区域归一化(normalized)了

borderType =BORDER_DEFAULT:用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT,我们一般不去管它。

二、自定义掩码

Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记

Mat kernel_ = (Mat_<char>(3, 3) << 0, -1, 0, 
							      -1, 5, -1, 
		                           0, -1, 0);
void filter2D(
InputArray src,     输入图像
OutputArray dst,     输出图像,和输入图像具有相同的尺寸和通道数量
int ddepth,      目标图像深度,为-1时保持输入图像通道深度
InputArray kernel,    卷积核
Point anchor=Point(-1,-1),表示过滤点在内核中的相对位置的内核锚;锚应位于内核内;默认值(-1-1)表示锚点位于内核中心。
double delta=0,     在储存目标图像前可选的添加到像素的值,默认值为0
int borderType=BORDER_DEFAULT   默认值是BORDER_DEFAULT,即对全部边界进行计算。
);

Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记

void QuickDemo::custom_mask_Demo(Mat& image) {
	// 自定义filter函数实现
	int offset = image.channels();
	int cols = (image.cols - 1) * offset;
	int rows = image.rows;
	Mat dst = Mat::zeros(image.size(), image.type());
	for (int row = 1; row < (rows - 1); row++) {
		const uchar* previous = image.ptr<uchar>(row-1);
		const uchar* current = image.ptr<uchar>(row);
		const uchar* next = image.ptr<uchar>(row+1);
		uchar* output = dst.ptr<uchar>(row);
		for (int col = offset; col < cols; col++) {
			output[col] = saturate_cast<uchar>(5 * current[col] - (current[col - offset] + current[col + offset] + previous[col] + next[col]));
		}
	}
	imshow("dst", dst);

	// opencv自带filter2D函数实现
	Mat dst2;
	Mat kernel_ = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
	filter2D(image.clone(), dst2, image.depth(), kernel_);
	imshow("dst2", dst2);
}

可以看出dst2没有黑边了,边缘被处理了。
Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记

三、边缘处理

在卷积开始之前增加边缘像素,填充的像素值为0或者RGB黑色,比如3x3在
四周各填充1个像素的边缘,在卷积处理之后再去掉这些边缘,这样就确保图像的边缘被处理

void copyMakeBorder(
InputArray src,     // 输入图像
OutputArray dst,  // 输出图像
int top,       // 填充边缘长度,一般上下左右都取相同值
int bottom,
int left,
int right,
int borderType,   // 填充类型
const Scalar& value = Scalar() // 边框颜色值,边框类型=BUALE_CONTER时才有用
)

openCV中的处理方法是:

BORDER_DEFAULT  - 默认的处理(镜像边界像素:1234|4321) BORDER_CONSTANT – 填充边缘用指定像素值
BORDER_REPLICATE – 填充边缘像素用已知的边缘像素值。(复制边界像素:1234|4444) BORDER_WRAP –
用另外一边的像素来补偿填充 使用参数

BORDER_CONSTANT = 0
BORDER_REPLICATE = 1
BORDER_REFLECT = 2
BORDER_REFLECT_101 = 4,
BORDER_REFLECT101 = BORDER_REFLECT_101,
BORDER_DEFAULT = BORDER_REFLECT_101,
BORDER_WRAP = 3,
BORDER_TRANSPARENT = 5,

源文件 quick_demo.cpp:实现类与公共函数

void QuickDemo::edge_process_Demo(Mat& image) {
	Mat dst0, dst1;
	copyMakeBorder(image, dst0, 5, 5, 5, 5, BORDER_REFLECT);
	copyMakeBorder(image, dst1, 5, 5, 5, 5, BORDER_CONSTANT,Scalar(0,255,255));
	imshow("REFLECT", dst0);
	imshow("CONSTANT", dst1);
}

Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记

四、Sobel算子

实现步骤:

x轴方向求导 —— y轴方向求导 —— 最终结果为二者相加

函数原型:

Sobel(src,ddepth,dx,dy,ksize=3,…)

离散微分算子(discrete differentiation operator),用来计算图像灰度的近似梯度
Soble算子功能集合高斯平滑和微分求导
一阶微分算子,求导算子,在水平和垂直两个方向上求导,得到图像X方法与Y方向梯度图像
Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记

代码案例:

chess = cv2.imread('chess.png')
# 求y方向边缘
dy = cv2.Sobel(chess, cv2.CV_64F, 1, 0, ksize=5)
# 求x方向边缘
dx = cv2.Sobel(chess, cv2.CV_64F, 0, 1, ksize=5)
# 二者相加
result = dy + dx

cv2.imshow('chess', chess)
cv2.imshow('dy', dy)
cv2.imshow('dx', dx)
cv2.imshow('result', result)
cv2.waitKey(0)

Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记

从上图可以明显看出,当dx设置为1时,求得y方向上的边缘信息,反之也是,最终二者相加的结果也就是Sobel算子的结果。不能一开始就设定dx,dy为1,这样子不能达到该效果;

五、Scharr算子

定义:与Sobel类似,但使用的kernel值不同,并且只能为3x3,只能求x方向或y方向一个方向的边缘信息;
由于Sobel算子求取导数的近似值,kernel=3时不是很准确,图像中较弱的边缘提取效果较差,OpenCV使用改进版本Scharr函数,算子如上右图:

例如一个 3 * 3 的 Sobel 算子,在梯度角度水平或垂直方向时,其不精确性就非常明显。Scharr 算子是对 Sobel 算子差异性的增强,两者之间的在检测图像边缘的原理和使用方式上相同。

而 Scharr 算子的主要思路是通过将模版中的权重系数放大来增大像素值间的差异,也是计算 x 或 y 方向上的图像差分
sobel,Scharr算子等此类算子都是:输出图像深度 >= 输入图像深度 。
Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记

void Sobel(
InputArray src,     输入图像(单通道)
OutputArray dst,     输出图像
int ddepth,       输出图像深度 (>= 输入图像深度)
int dx,         x梯度(几阶导数)一般为012,其中0表示这个方向上没有求导
int dy,         y梯度(几阶导数)
int ksize = 3,      滤波窗口大小(357…)
double scale = 1,    是否缩放,默认=1.0
double delta = 0,     偏移常数
int borderType = BORDER_DEFAULT )  图像边缘处理方式。默认值=cv2.BORDER_DEFAULT

在经过处理后,需要用 convertScaleAbs() 函数将其转回原来的uint8形式,否则将无法显示图像,而只是一副灰色的窗口。

void convertScaleAbs(
InputArray src,       输入图像
OutputArray dst,    输出uint8类型图片
double alpha = 1,     伸缩系数
double beta = 0     偏移值:加到结果上的一个值
)

由于Sobel算子是在两个方向计算的,最后还需要用cv::addWeighted(src1, alpha, src2, beta, gamma, dst)函数将其组合起来。

//头文件 quick_opencv.h:声明类与公共函数
#pragma once
#include <opencv2\opencv.hpp>
using namespace cv;

class QuickDemo {
public:
	...
	void edge_extract_Demo(Mat& image1);
	void laplance_Demo(Mat& image1);
	void canny_Demo(Mat& image1);
};
//主函数调用该类的公共成员函数
#include <opencv2\opencv.hpp>
#include <quick_opencv.h>
#include <iostream>
using namespace cv;


int main(int argc, char** argv) {
	Mat src = imread("D:\\Desktop\\jianbian.png");
	if (src.empty()) {
		printf("Could not load images...\n");
		return -1;
	}
	QuickDemo qk;
	qk.edge_extract_Demo(src1);
	qk.laplance_Demo(src1);
	qk.canny_Demo(src1);
	waitKey(0);
	destroyAllWindows();
	return 0;
}
//源文件 quick_demo.cpp:实现类与公共函数
void QuickDemo::edge_extract_Demo(Mat& image) {
	Mat gau_dst, gray_dst, xgrad, ygrad;
	GaussianBlur(image, gau_dst, Size(3, 3), 10);
	cvtColor(gau_dst, gray_dst, COLOR_BGR2GRAY);

	//Sobel(gray_dst, xgrad, -1, 1, 0, 3);
	//Sobel(gray_dst, ygrad, -1, 0, 1, 3);

	//Sobel(gray_dst, xgrad, CV_16S, 1, 0, 3);
	//Sobel(gray_dst, ygrad, CV_16S, 0, 1, 3);

	Scharr(gray_dst, xgrad, CV_16S, 1, 0, 3);
	Scharr(gray_dst, ygrad, CV_16S, 0, 1, 3);
	convertScaleAbs(xgrad, xgrad);
	convertScaleAbs(ygrad, ygrad);

	Mat xygrad;
	addWeighted(xgrad, 0.5, ygrad, 0.5, 0, xygrad);
	imshow("xgrad", xgrad);
	imshow("ygrad", ygrad);
	imshow("xygrad", xygrad);

	Mat xy_grad = Mat::zeros(xgrad.size(),xgrad.type());
	int width = xgrad.cols;
	int height = xgrad.rows;
	for (int h = 0; h < height; h++) {
		uchar* current_x = xgrad.ptr<uchar>(h);
		uchar* current_y = ygrad.ptr<uchar>(h);
		uchar* current_d = xy_grad.ptr<uchar>(h);
		for (int w = 0; w < width; w++) {
			*current_d++ = saturate_cast<uchar>(*current_x++ + *current_y++);
		}
	}
	imshow("xy_grad", xy_grad);
}

输出图像深度:-1(与原图保持一致)
Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记
输出图像深度:CV_16S 方向梯度细节更多了。

Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记
使用自定义函数直接相加结果(右): (使用addWeighted函数,各方向梯度0.5的权重组合发虚:左)
Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记
测试scharr()效果:细节更加丰富
Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记

六、拉普拉斯算子

优点:可同时求得两个方向的边缘;

缺点:对噪音比较敏感,一般需要先进行去噪在调用拉普拉斯算子;

函数原型:

Laplacian(img,ddepth,ksize=1)
在二阶导数的时候,最大变化处的值为零即边缘是零值。通过二阶导数计算,依据此理论我们可以计算图像二阶导数,提取边缘。
Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记

void Laplacian(
InputArray src,      输入图像(单通道)
OutputArray dst,      输出图像
int ddepth,        输出图像深度 (>= 输入图像深度)
int ksize = 1,       滤波窗口大小(357…)
double scale = 1,     是否缩放,默认=1.0
double delta = 0,     偏移常数
int borderType = BORDER_DEFAULT   图像边缘处理方式
)

一般处理流程

高斯模糊 – 去噪声GaussianBlur()
转换为灰度图像cvtColor()
拉普拉斯 – 二阶导数计算Laplacian()
取绝对值convertScaleAbs()
显示结果

void QuickDemo::laplance_Demo(Mat& image) {
	Mat gau_dst, gray_dst, laplance_dst, ygrad;

	GaussianBlur(image, gau_dst, Size(3, 3), 10);
	cvtColor(gau_dst, gray_dst, COLOR_BGR2GRAY);

	Laplacian(gray_dst, laplance_dst, CV_16S, 3, 1.0, 0);
	convertScaleAbs(laplance_dst, laplance_dst);

	threshold(laplance_dst, laplance_dst, 0, 255, THRESH_OTSU | THRESH_BINARY);
	imshow("laplance_dst", laplance_dst);
}

Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记

chess = cv2.imread('chess.png')
result = cv2.Laplacian(chess, cv2.CV_64F, ksize=5)

cv2.imshow('chess', chess)
cv2.imshow('result', result)
cv2.waitKey(0)

Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记
从效果上看,比起Sobel步骤更加简单,并且效果也比较好,缺点就是如果噪声过多的话效果会比较差

十、Canny算法

实现步骤:

1、使用5x5高斯滤波消除噪音;

2、使用Sobel计算图像梯度的方向(0°、45°、90°、135°);

3、取局部极大值;

4、阈值计算;

函数原型:

Canny(img,minVal,maxVal,…)

其中的minVal和maxVal代表边缘的阈值,两者差值过大的话会损失一定的边缘信息;

代码案例:

img = cv2.imread('1.jpg')
result = cv2.Canny(img, 100, 200)

cv2.imshow('org', img)
cv2.imshow('result', result)
cv2.waitKey(0)

Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记
Canny算法介绍 - 非最大信号抑制
Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记
T1, T2为阈值,凡是高于T2的都保留,凡是小于T1都丢弃,从高于T2的像素出发,凡是大于T1而且相互连接的,都保留。最终得到一个输出二值图像。
推荐的高低阈值比值为 T2: T1 = 3:1/2:1其中T2为高阈值,T1为低阈值

void Canny(
InputArray image,        输入图像(单通道)
OutputArray edges,     输出图像
double threshold1,      阈值T1
double threshold2,     阈值T2 一般为 2*T1
int apertureSize = 3,     Soble算子的size窗口大小 
bool L2gradient = false   默认false L1归一化,Ture则为L2归一化
);

一般处理流程

高斯模糊 - GaussianBlur
灰度转换 - cvtColor
计算梯度 – Sobel/Scharr
非最大信号抑制
高低阈值输出二值图像

void QuickDemo::canny_Demo(Mat& image) {
	Mat gau_dst, gray_dst, grad_dst;

	GaussianBlur(image, gau_dst, Size(3, 3), 10);
	cvtColor(gau_dst, gray_dst, COLOR_BGR2GRAY);

	Canny(gray_dst, grad_dst, 50.0, 100.0, 3, false);
	imshow("grad_dst", grad_dst);
}

Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理,Opencv_C++学习笔记,opencv,c++,笔记文章来源地址https://www.toymoban.com/news/detail-603383.html

到了这里,关于Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Opencv-C++笔记 (15) : 像素重映射 与 图像扭曲

    重映射,就是把一幅图像中某位置的像素放置到另一图像指定位置的过程。即: 在重映射过程中,图像的大小也可以同时发生改变。此时像素与像素之间的关系就不是一一对应关系,因此在重映射过程中,可能会涉及到像素值的插值计算。 头文件 quick_opencv.h:声明类与公共

    2024年02月13日
    浏览(51)
  • Opencv-C++笔记 (16) : 几何变换 (图像的翻转(镜像),平移,旋转,仿射,透视变换)

    图像旋转是指图像按照某个位置转动一定的角度的过程,旋转中图像仍保持着原始尺寸。图像旋转后图像水平对称轴、垂直对称轴及中心坐标原点都可能会发生变换,因此需要对图像旋转中的坐标进行相应转换。 假设有一个点:P(x,y),它在绕原点 O(0,0) 旋转 β 后,被转换成

    2024年02月14日
    浏览(70)
  • Opencv-C++笔记 (12) : opencv-仿射变化

    介绍完图像的缩放和翻转后,接下来将要介绍图像的旋转,但是在OpenCV 4中并没有专门用于图像旋转的函数,而是通过图像的仿射变换实现图像的旋转。实现图像的旋转首先需要确定旋转角度和旋转中心,之后确定旋转矩阵,最终通过仿射变换实现图像旋转。 针对这个流程,

    2024年02月11日
    浏览(50)
  • Opencv-C++笔记 (2) : opencv的矩阵操作

    OpenCV中的矩阵操作非常重要,本文总结了矩阵的创建、初始化以及基本矩阵操作,给出了示例代码,主要内容包括: 建立矩阵必须要指定矩阵存储的数据类型,图像处理中常用的几种数据类型如下: 包括数据位深度8位、32位,数据类型U:uchar、F:float型以及通道数C1:单通道、

    2024年02月11日
    浏览(49)
  • Opencv-C++笔记 (5) : opencv-形态学

    形态学运算是针对二值图像依据数学形态学(Mathematical Morphology)的集合论方法发展起来的图像处理方法。数学形态学起源于岩相学对岩石结构的定量描述工作,近年来在数字图像处理和机器视觉领域中得到了广泛的应用,形成了一种独特的数字图像分析方法和理论。 结构元素

    2024年02月09日
    浏览(53)
  • Opencv-C++笔记 (6) : opencv-图片和视频操作

    filename:需要读取图像的文件名称,包含图像地址、名称和图像文件扩展名 flags:读取图像形式的标志,如将彩色图像按照灰度图读取,默认参数是按照彩色图像格式读取,可 选参数在表2-3给出。 函数用于读取指定的图像并将其返回给一个Mat类变量,如果图像文件不存在、破

    2024年02月09日
    浏览(48)
  • Opencv-C++笔记 (9) : opencv-多通道分离和合并

    在图像颜色模型中不同的分量存放在不同的通道中,如果我们只需要颜色模型的某一个分量,例如只需要处理RGB图像中的红色通道,可以将红色通道从三通道的数据中分离出来再进行处理,这种方式可以减少数据所占据的内存,加快程序的运行速度。同时,当我们分别处理完

    2024年02月09日
    浏览(50)
  • Opencv-C++笔记 (18) : 轮廓和凸包

    轮廓发现是基于图像边缘提取的基础寻找对象轮廓的方法。 所以边缘提取的阈值选定会影响最终轮廓发现结果 轮廓查找步骤: 输入图像转为灰度图像cvtColor 使用Canny进行边缘提取或者threshold阈值操作,得到二值图像 使用findContours寻找轮廓 使用drawContours绘制轮廓 在二值图像

    2024年02月11日
    浏览(42)
  • Opencv-C++笔记 (7) : opencv-文件操作XML和YMAL文件

    除了图像数据之外,有时程序中的尺寸较小的Mat类矩阵、字符串、数组等 数据也需要进行保存,这些数据通常保存成XML文件或者YAML文件。本小节中将介绍如何利用OpenCV 4中的函数将数据保存成XML文件或者YAML文件以及如何读取这两种文件中的数据。 XML是一种元标记语言,所谓

    2024年02月09日
    浏览(72)
  • Opencv-C++笔记 (3) : opencv的库介绍以及和C++对接转换

    calib3d 主要包含相机标定,立体视觉的功能:物体姿势估计,三维重建,摄像头标定 core,包含库的基本结构和操作,比如数据结构,绘图函数,数组操作等函数 dnn,深度学习模块,包含构建网络,加载序列化的模型,但是不支持训练,只能推理 features2d,处理图像特征点,特

    2024年02月09日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包