记录OpenCV过滤用法,小白。
Mat读取灰度图像
Mat src = new Mat("1.jpg", ImreadModes.Grayscale);//灰度读取
ImreadModes参数
//If set, return the loaded image as is (with alpha channel, otherwise it gets cropped).
Unchanged = -1,
//If set, always convert image to the single channel grayscale image.
//单通道灰度图像
Grayscale = 0x0,
//If set, always convert image to the 3 channel BGR color image.
Color = 0x1,
//If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit.
AnyDepth = 0x2,
//If set, the image is read in any possible color format.
AnyColor = 0x4,
//If set, use the gdal driver for loading the image.
LoadGdal = 0x8,
//If set, always convert image to the single channel grayscale image and the image size reduced 1/2.
//灰度读取,并将图像大小减小1/2
ReducedGrayscale2 = 0x10,
//If set, always convert image to the 3 channel BGR color image and the image size reduced 1/2.
ReducedColor2 = 0x11,
//If set, always convert image to the single channel grayscale image and the image size reduced 1/4.
ReducedGrayscale4 = 0x20,
//If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4.
ReducedColor4 = 0x21,
//If set, always convert image to the single channel grayscale image and the image size reduced 1/8.
ReducedGrayscale8 = 0x40,
//If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8.
ReducedColor8 = 0x41,
//If set, do not rotate the image according to EXIF's orientation flag.
IgnoreOrientation = 0x80
GaussianBlur 高斯滤波
高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,我觉得就是模糊处理,图片变的平滑柔和。
函数API
void GaussianBlur(InputArray src,
OutputArray dst,
Size ksize,
double sigmaX,
double sigmaY=0,
int borderType=BORDER_DEFAULT);
src,输入图像,即源图像,填Mat类的对象即可。它可以是单独的任意通道数的图片,
但需要注意,图片深度应该为CV_8U,CV_16U, CV_16S, CV_32F 以及 CV_64F之一。
dst,即目标图像,需要和源图片有一样的尺寸和类型。比如可以用Mat::Clone,以源图片为模板,
来初始化得到如假包换的目标图。
ksize,高斯内核的大小。其中ksize.width和ksize.height可以不同,但他们都必须为正数和奇数
(并不能理解)。或者,它们可以是零的,它们都是由sigma计算而来。
sigmaX,表示高斯核函数在X方向的的标准偏差。
sigmaY,表示高斯核函数在Y方向的的标准偏差。若sigmaY为零,就将它设为sigmaX,
如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height计算出来(就是自动)。
MedianBlur 中值滤波
中值滤波将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的【中值】代替。我用来去除地板方格很有效。
函数API
void MedianBlur( InputArray src, OutputArray dst, int ksize );
src:源图像Mat对象
dst:目标图像Mat对象
ksize:滤波模板的尺寸大小,必须是大于1的奇数,如:3,5,7等
BoxFilter 方框滤波(盒子滤波)
方框滤波是均值滤波的一般形式,在均值滤波中,将滤波器中所有的像素值求和后的平均值作为滤波后结果,方框滤波也是求滤波器内所有像素值的之和,但是方框滤波可以选择不进行归一化,就是将所有像素值的和作为滤波结果,而不是所有像素值的平均值。
- 优势:快
函数API
void BoxFilter(InputArray src, OutputArray dst, int ddepth,
Size ksize, Point anchor = Point(-1,-1),
bool normalize = true,
int borderType = BORDER_DEFAULT)
src:输入图像。
dst:输出图像,与输入图像具有相同的尺寸和通道数。
ddepth:输出图像的数据类型(深度),根据输入图像的数据类型不同拥有不同的取值范围,具体的取值范围在表5-1给出,当赋值为-1时,输出图像的数据类型自动选择。
ksize:卷积核尺寸。
anchor:内核的基准点(锚点),其默认值为(-1,-1)代表内核基准点位于kernel的中心位置。基准点即卷积核中与进行处理的像素点重合的点,其位置必须在卷积核的内部。
normalize:是否将卷积核进行归一化的标志,默认参数为true,表示进行归一化。
borderType:像素外推法选择标志,取值范围在表3-5中给出,默认参数为BORDER_DEFAULT,表示不包含边界值倒序填充。
SqrBoxFilter 和BoxFilter区别不大
Sobel算子
sobel算子是一种计算不同方向上梯度的工具。原理是使用[卷积核]对图像进行处理。该算子结合了高斯平滑和微分求导运算,利用局部差分寻找边缘,计算所得的是一个梯度的近似值。
如果想计算x方向梯度,我们就需要这样的一个卷积核
以卷积核的中心为中心,将卷积核与图像上[像素]值一一对应,卷积核上的数字相当于系数。利用如下公式即可计算出卷积核中心的x方向梯度。
同理,如果想要计算y方向的梯度,卷积核应该是这样的,公式也是同理。
在 [OpenCV]内,使用函数 cv2.Sobel()实现 Sobel 算子运算。
函数API
void Sobel(InputArray src, OutputArray dst, MatType ddepth, int xorder,
int yorder, int ksize = 3, double scale = 1.0, double delta = 0.0,
BorderTypes borderType = BorderTypes.Reflect101)
src 代表源图像。
dst 代表目标图像。
ddepth 处理结果图像深度,一般我们都填-1,即与原图深度相同。
但在这里我们需要填写cv2.CV_64F。简单来说就是如果填写-1,
我们在计算梯度时产生的负数就会被程序默认为0,导致有一边的边缘出不来。
而cv2.CV_64F范围更大,可以保留负数。
dx 代表 x 方向上的求导阶数。
dy 代表 y 方向上的求导阶数。
ksize 代表 Sobel 核的大小。卷积核的尺寸。默认为3,即3*3的矩阵。
scale 代表计算导数值时所采用的缩放因子,默认情况下该值是 1,是没有缩放的。
delta 代表加在目标图像 dst 上的值,该值是可选的,默认为 0。
borderType 代表边界样式
ConvertScaleAbs 和 AddWeighted
Sobel分别计算完x、y方向的权值时,里面是有负数的。我们需要对这些负数取绝对值,否则照样会被归为0。
ConvertScaleAbs 取绝对值
AddWeighted 图像融合,权重加法函数
ConvertScaleAbs(InputArray src, OutputArray dst, double alpha = 1.0, double beta = 0.0)
src 源图像。
dst 处理后图像。
alpha 代表调节系数,默认为 1。
beta 代表调节亮度值,默认为 0。
AddWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1)
src1, src2:需要融合相加的两副大小和通道数相等的图像
dst 处理后图像。
alpha:src1的权重,和beta值相同就是完全融合,不同时,类似透明图那种
beta:src2的权重
gamma:gamma修正系数,不需要修正设置为0
dtype:输出图像数组的深度,即图像单个像素值的位数(如RGB用三个字节表示,则为24位),选默认值表示与源图像保持一致。
Canny边缘检测算法
一个多级边缘检测算法,Canny使用滞后阈值,滞后阈值需要两个阈值(高阈值和低阈值)
Canny使用两种不同的阈值分别检测强边缘和弱边缘,并且仅当弱边缘和强边缘相连时,才将边缘包含在输出图像中。因此不容易被噪声“填充”,更容易检测出真正的弱边缘
void Canny(InputArray src, OutputArray edges, double threshold1,
double threshold2, int apertureSize = 3, bool L2gradient = false)
image:输入图像,必须是CV_8U的单通道或者三通道图像。
edges:输出图像,输出的边缘图像,8bit单通道,宽高与输入图像一致
threshold1:第一个滞后阈值,低阈值。
threshold2:第二个滞后阈值,高阈值,Canny 推荐的 高:低 阈值比在 2:1 到3:1之间。
apertureSize:Sobel算子的直径。
L2gradient:是否使用更精确的方式计算梯度,True使用,否则不用
FindContours 寻找图像轮廓
void FindContours(InputArray image, out Point[][] contours,out HierarchyIndex[] hierarchy,
RetrievalModes mode, ContourApproximationModes method, Point? offset = null)
- image:输入图像,图像必须为8-bit单通道图像
- contours:检测到的轮廓,每个轮廓都是以点向量的形式进行存储
- hierarchy:可选的输出向量(std::vector),包含了图像的拓扑信息,作为轮廓数量的表示hierarchy包含了很多元素,每个轮廓contours[i]对应hierarchy中hierarchy[i][0]~hierarchy[i][3],分别表示后一个轮廓,前一个轮廓,父轮廓,内嵌轮廓的索引,如果没有对应项,则相应的hierarchy[i]设置为负数
- mode:轮廓检索模式
RETR_EXTERNAL:表示只检测最外层轮廓,对所有轮廓设置hierarchy[i][2]=hierarchy[i][3]=-1
RETR_LIST:提取所有轮廓,并放置在list中,检测的轮廓不建立等级关系
RETR_CCOMP:提取所有轮廓,并将轮廓组织成双层结构(two-level hierarchy),顶层为连通域的外围边界,次层位内层边界
RETR_TREE:提取所有轮廓并重新建立网状轮廓结构(信息完整)
RETR_FLOODFILL:
- method:轮廓逼近方法,是检测方法,不是输出结果
CHAIN_APPROX_NONE:获取每个轮廓的每个点,相邻的两个点的像素位置差不超过1
CHAIN_APPROX_SIMPLE:压缩水平、垂直和对角线段,也就是函数只留下它们的结束点。如果一个矩形轮廓只需4个点来保存轮廓信息
CHAIN_APPROX_TC89_L1:应用Chin chain近似算法的一种风格。
CHAIN_APPROX_TC89_KCOS:应用Chin CHAIN approxing算法的一种风格