目录

预备知识

滤波、核和卷积

边界外推和边界处理

阈值化操作

Otsu算法

自适应阈值

平滑

简单模糊和方框型滤波器

中值滤波器

高斯滤波器

双边滤波器

导数和梯度

索贝尔导数

Scharr滤波器

拉普拉斯变换

图像形态学

膨胀和腐蚀

通用形态学函数

开操作和闭操作

形态学梯度

顶帽和黑帽

自定义核

用任意线性滤波器做卷积

用cv::filter2D()进行卷积

通过cv::sepFilter2D使用可分核

生成卷积核


预备知识

滤波、核和卷积

滤波器指的是一种由一幅图像 I(x,y)根据像素点x,y附近的区域计算得到一幅新图像 I'(x,y)的算法。其中,模板规定了滤波器的形状以及这个区域内像素的值的组成规律,也称“滤波器”或“核”。在下面的介绍中多采用的是线性核,即 I'(x,y)的像素的值由 I(x,y)及其周围的像素的值的加权相加得来的。可由以下方程表示:

(A)5×5盒状核 (B)规范化的5×5盒状核 (C)3×3的Sobel核 (D)5×5规范化高斯核

注:“锚点”均用粗体表示

边界外推和边界处理

自定义边框

在处理图像时,只要告诉调用的函数添加虚拟像素的规则,库函数就会自动创建虚拟像素。cv::copyMakeBorder()就是一个为图像创建边框的函数。

cv::copyMakeBorder(InputArray src, InputArray dst, int top, int bottom, int left, int right, int borderType, const cv::Scalar& value=cv::Scalar())

作用:通过指定两幅图像,同时指明填充方法,该函数就会将第一幅图填补后的结果保存在第二幅图像中。其中,src是原图像,dst是填充后的图像,top、bottom、left、right分别是四个方向上的尺寸,borderType是像素填充的方式,value是常量填充时的值。

borderType的取值及效果
取值 效果
cv::BORDER_CONSTANT 为每个边框像素赋予一个相同的值。
cv::BORDER_WRAP 类似于平铺扩充
cv::BORDER_REPLICATE 复制边缘的像素扩充
cv::BORDER_REFLECT 通过镜像复制扩充
cv::BORDER_REFLECT_101 通过镜像复制扩充,边界像素除外
cv::BORDER_DEFAULT cv::BORDER_REFLECT_101

自定义外推

int cv::borderInterpolate(int p, int len, int borderType)

作用:计算一个维度上的外推,p为原图上一个坐标,len是p指维度上的大小,borderType是边界类型。

例子:混合的边界条件下计算一个特定像素的值,在一维中使用BORDER_REFLECT_101,在二维中使用BORDER_WRAP:

float val = img.at<float>(cv::borderInterpolate(100, img.rows, cv::BORDER_REFLECT_101),cv::borderInterpolate(-5, img.cols, cv::BORDER_WRAP)
)

阈值化操作

阈值化操作的原理是对于数组中每个值,根据其高于或低于某个阈值做出相对应的处理,OpenCV中提供了实现这种功能的方法cv::threshold()。

double cv::threshold(InputArray src, cv::OutputArray dst, double thresh, double maxValue, int thresholdType)

thresholdType的可选项及其操作
阈值类型 操作
cv::THRESH_BINARY
cv::THRESH_BINARY_INV
cv::THRESH_TRUNC
cv::THRESH_TOZERO
cv::THRESH_TOZERO_INV

不同阈值类型对应的结果

例一:将一幅图像的三个通道相加并将像素值限制在100以内

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>using namespace std;void sum_rgb(const cv::Mat& src, cv::Mat& dst) {// 分通道vector<cv::Mat> planes;cv::split(src, planes);cv::Mat b = planes[0];cv::Mat g = planes[1];cv::Mat r = planes[2];cv::Mat s;// 加权融合,防止越界cv::addWeighted(r, 1. / 3, g, 1. / 3, 0.0, s);cv::addWeighted(s, 1., r, 1. / 3, 0.0, s);// 阈值化操作cv::threshold(s, dst, 100, 100, cv::THRESH_TRUNC);
}void help() {cout << "Call: ./ch10_ex10_1 faceScene.jpg" << endl;cout << "Show use of alpha blending (addWeighted) and threshold" << endl;
}int main()
{help();cv::Mat src = cv::imread("D:\\personal-data\\wallpapers\\test.png");cv::Mat dst;if (src.empty()){cout << "can not load the image" << endl;return -1;}sum_rgb(src, dst);cv::imshow("img", dst);cv::waitKey(0);cv::destroyAllWindows();return 0;
}

运行结果:

例二:对于浮点型图像进行三个通道相加并将像素值限制在100以内

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>using namespace std;void sum_rgb(const cv::Mat& src, cv::Mat& dst) {// 分通道vector<cv::Mat> planes;cv::split(src, planes);cv::Mat b = planes[0];cv::Mat g = planes[1];cv::Mat r = planes[2];// 全0初始化s矩阵cv::Mat s = cv::Mat::zeros(b.size(), CV_32F);// accumulate可将8位整型的图像累加到一幅浮点型的图像中cv::accumulate(b, s);cv::accumulate(g, s);cv::accumulate(r, s);// 阈值化操作cv::threshold(s, dst, 100, 100, cv::THRESH_TRUNC);s.convertTo(dst, b.type());
}void help() {cout << "Call: ./ch10_ex10_1 faceScene.jpg" << endl;cout << "Show use of alpha blending (addWeighted) and threshold" << endl;
}int main()
{help();cv::Mat src = cv::imread("D:\\personal-data\\wallpapers\\test.png");cv::Mat dst;if (src.empty()){cout << "can not load the image" << endl;return -1;}sum_rgb(src, dst);cv::imshow("img", dst);cv::waitKey(0);cv::destroyAllWindows();return 0;
}

运行结果:

Otsu算法

函数cv::threshold()也可以自动决定最优的阈值,只需将参数thresh传递值cv::THRESH_OTSU即可。

简而言之,Otsu算法就是遍历所有可能的阈值,然后对每个阈值结果的两类像素(低于阈值和高于阈值两类像素)计算方差,然后计算的值,取其最小的阈值。

式中,是根据两类像素的数量计算而来的权重。由于要遍历所有可能的阈值,所以这并不是一个相对高效的过程。

自适应阈值

自适应阈值方法中阈值在整个过程中自动产生变化,这由OpenCV中的cv::adaptiveThreshold()实现。

void cv::adaptiveThreshold(InputArray src, OutputArray dst, double maxValue, int adaptiveMethod, int threshType, int blockSize, double C)

该方法是逐个像素地计算自适应阈值T(x, y),具体计算过程是:计算每个像素位置周围的blockSize×blockSize区域的加权平均值,然后减去常数C。求均值时所用权重和adaptiveMethod有关,若是cv::ADAPTIVE_THRESH_MEAN_C,则权重相等,若是cv::ADAPTIVE_THRESH_GAUSSIAN_C,则权重由高斯方差得到。

注:该方法只适应与单通道8位或浮点型图像

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>using namespace std;int main()
{// 设置参数double fixed_threshold = 15;int threshold_type = 1 ? cv::THRESH_BINARY : cv::THRESH_BINARY_INV;int adaptive_method = 1 ? cv::ADAPTIVE_THRESH_MEAN_C : cv::ADAPTIVE_THRESH_GAUSSIAN_C;int block_size = 71;double offset = 15;// 以灰度图形式加载图片cv::Mat Igray = cv::imread("D:\\personal-data\\wallpapers\\test.png", cv::IMREAD_GRAYSCALE);// 判断图像是否加载成功if (Igray.empty()) { cout << "Can not load " << "D:\\personal-data\\wallpapers\\test.png" << endl; return -1; }// 声明输出矩阵cv::Mat It, Iat;// 阈值化操作cv::threshold(Igray,It,fixed_threshold,255,threshold_type);// 自适应阈值cv::adaptiveThreshold(Igray,Iat,255,adaptive_method,threshold_type,block_size,offset);// 展示结果图像cv::imshow("Raw", Igray);cv::imshow("Threshold", It);cv::imshow("Adaptive Threshold", Iat);cv::waitKey(0);cv::destroyAllWindows();return 0;
}

运行结果:

当threshold_type=1且adaptive_method=1

原图

阈值化操作

自适应阈值化

当threshold_type=0且adaptive_method=0

原图

阈值化操作

自适应阈值化

平滑

平滑也称“模糊”,是一种简单而又常用的图像处理操作。平滑图像的目的有很多,但通常都是为了减少噪声和伪影。在降低图像分辨率的时候,平滑也十分重要,可以防止图片出现锯齿状。

简单模糊和方框型滤波器

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

作用:实现简单的滤波,目标图像中的每个值都是原图像中相应位置一个窗口(核)中像素的平均值,窗口的尺寸由ksize声明;anchaor指定计算时核与源图像的对齐方式,默认情况下anchor为cv::Point(-1, -1),表示核相对于滤波器居中。

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

作用:方框滤波器是一种矩形的并且滤波器中所有值全部相等的滤波器。通常,所有的为1或者1/A,其中A是滤波器的面积。后一种滤波器称为“归一化方框型滤波器”,下面所示的是一个5×5的模糊滤波器,也称“归一化方框型滤波器”。

通过上述介绍,可以发现cv::boxFilter()是一种一般化的形式,而cv::blur()是一种特殊化的形式。但前者可以以非归一化形式调用,并且输出图像深度可以控制,但后者智能以归一化形式调用,且输出图像深度必须和原图像保持一致。

中值滤波器

中值滤波器(Median Filter)将每个像素替换为围绕这个像素的矩形领域内的中值或“中值”像素(相对于平均像素)。通过均值滤波器对噪声图像,尤其是有较大孤立的异常值非常敏感,少量具有较大偏差的点也会严重影响到均值滤波器。中值滤波器可以采用取其中间点的方式来消除异常值。

void cv::medianBlur(InputArray src, OutputArray dst, Size ksize)

高斯滤波器

关于高斯滤波器,在之前的文章中已做了详细介绍,可以参考OpenCV高斯滤波GaussianBlur

双边滤波器

双边滤波器是一种比较大的图像分析算子,也就是边缘保持平滑。高斯平滑的模糊过程是减缓像素在空间上的变化,因此与邻近的关系紧密,而随机噪声在像素间的变化幅度又会非常的大(即噪声不是空间相关的)。基于这种前提高斯平滑很好地减弱了噪声并且保留了小信号,但是却破坏了边缘信息,边缘也模糊了。

和高斯平滑类似,双边滤波对每个像素及其领域内的像素进行了加权平均。其权重由两部分组成,第一部分同高斯平滑,第二部分也是高斯权重,但是它不是基于空间距离而是色彩强度差计算而来的,在多通道(色彩)图像上强度差由各分量的加权累加代替。可将其当做高斯平滑,指示相似程度更高的像素权值更高,边缘更加明显,对比度更高。

cv::bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType= cv::BORDER_DEFAULT)

参数:d是像素邻近的最大距离,处理视频时一般不大于5,非实时应用时可放大到9;sigmaColor是色彩空间滤波器的sigma值,该值越大,则色彩强度越大,不连续性越强;sigmaSpace是坐标空间滤波器的sigma值。

导数和梯度

卷积中最重要也是最基本的部分就是(近似)计算导数。

索贝尔导数

一般来说,用来表示微分的最常用的算子是索贝尔(Sobel)导数算子,可以实现任意阶导数和混合偏导数。

void sv::Sobel(InputArray src, OutputArray dst, int ddepth, int xorder, int yorder, cv::Size ksize=3, double scale=1, double delta=0, int borderType=cv::BORDER_DEFAULT)

参数:ddepth指明目标图像的深度或类型;xorder和yorder是求导顺序,其取值可为0,、1或2,其中0代表在该方向不求导,kszie是一个奇数,表示滤波器核的大小, 目前最大到31;阈值和偏移量在结果存入dst前进行调用,公式如下:

Sobel算子的好处是可以将核定义为各种大小,并且可以快速迭代式地构造这些核。大的核可以更好地近似导数,因为可以消除噪声影响。其缺点是如果导数在空间上变化剧烈,核太大会使结果发生偏差,并且核比较小时准确度不高。

实际上,由于Sobel算子定义在离散空间上,所以它并不是真正的导数,而是一个多项式,即在x方向上进行Sobel运算表示的并不是二阶导数,而是对抛物线函数的局部拟合。

Scharr滤波器

为了将图像内的信息联系起来,可能需要测量一幅图像:在处理过程中,通过在目标附近组织一幅梯度直方图来收集其形状信息,这些直方图是许多形状分类器训练和使用的基础。因此,梯度角的误差会降低分类器识别的效果。

对于3×3的Sobel滤波器,梯度角距离水平或垂直方向越远,误差越明显。在OpenCV中,调用cv::Sobel()时设置ksize为cv::SCHARR,即可消除3×3这样小但是快的Sobel导数滤波器所带来的误差。Scharr滤波器核Sobel滤波器同样很快,但是前者精度更高。因此选择3×3的滤波器时,应当使用Scharr滤波器。

     或     

拉普拉斯变换

OpenCV中的函数Laplacian实现了对拉普拉斯算子的离散近似:

void sv::Laplacian(InputArray src, OutputArray dst, int ddepth, cv::Size ksize=3, double scale=1, double delta=0, int borderType=cv::BORDER_DEFAULT)

只要ksize不为1,Laplacian算子的实现就是直接计算Sobel算子响应之和。当ksize=1时的卷积核如下所示:

Laplacian算子可应用于各种场景处理,一种常见的应用就是匹配“斑点”。Laplacian算子就是图像在x和y轴方向的导数之和,这意味着一个被较大值包围的点或小斑点(比ksize小)处的值将会变得很大。相反,被较小值包围的点或小斑点处的值将在负方向上变得很大。

Laplacian算子同样可以用于边缘检测,函数一阶导数在原函数变化大的地方,值会相应变大,同样在图像边缘处也同样变化,所有导数在这些地方将变得很大。因此可以在二阶导数为0的地方搜寻这么一个极大值,原图像中的边缘通过Laplacian算子运算后会变成0。对于有些不是边缘也变成0的问题,可以通过滤掉Sobel一阶导数中较大值的点解决。

图像形态学

OpenCV提供了一种高效且易用的图像形态学变换接口。其中有很多形态学方法,但基本上所有的形态学操作都基于两种原始操作——膨胀与腐蚀。

膨胀和腐蚀

膨胀和腐蚀是最基本的形态学变换,可用于消除噪声、元素分割和连接等。基于这两种操作,可以实现更复杂的形态学操作,用来定位强度峰值或孔洞、另一种形式的图像梯度等。

膨胀是一种卷积操作,它将目标像素的值替换为卷积核覆盖区域的局部最大值,扩张了明亮区域,填充凹面。此卷积核是一个非线性核,是一个四边形或圆形的实心核,其锚点在中心。与膨胀对应,腐蚀是与之相反的操作,腐蚀操作计算的是核覆盖范围内的局部最小值缩减了明亮区,消除凸起。

原图

膨胀

腐蚀

void cv::erode(InputArray src, OutputArray dst, InputArray element, cv::Point anchor=cv::Point(-1, -1), int iterations=1 int borderType=cv::BORDER_CONSTANT, const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue())

void cv::dilate(InputArray src, OutputArray dst, InputArray element, cv::Point anchor=cv::Point(-1, -1), int iterations=1 int borderType=cv::BORDER_CONSTANT, const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue())

以上两个函数分别是膨胀和腐蚀对应的函数,第三个参数是核,可以传递一个未初始化的cv::Mat,会使用默认的锚点在中心的3×3的核。

腐蚀操作通常用于消除图中斑点一样的噪声,原理是斑点经过腐蚀后会消失,而大的可见区域不会受影响。膨胀操作通常用于发生连通分支。

通用形态学函数

当处理的对象是二值图像时,像素只能是开(>0)或关(=0)的图像掩膜时,基本的腐蚀和膨胀操作就够用了。需要对灰度图或者彩色图进行处理时,一些其他操作就非常有用了,这些操作可以通过cv::morphologyEx()实现。

void cv::morphologyEx(InputArray src, OutputArray dst, int op, InputArray element, cv::Point anchor=cv::Point(-1, -1), int iterations=1, int borderType=cv::BORDER_CONSTANT, const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue())

cv::morphologyEx()操作op选项
操作值 形态学操作 是否需要临时图像
cv::MORPH_OPEN 开操作
cv::MORPH_CLOSE 闭操作
cv::MORPH_GRADIENT 形态学梯度 总是需要
cv::MORPH_TOPHAT 顶帽操作 就地调用需要(src = dst)
cv::MORPH_BLACKHAT 地貌操作 就地调用需要(src = dst)

开操作和闭操作

开操作先将图像进行腐蚀,然后对腐蚀的结果进行膨胀。开操作常用语对二值图像中的区域进行计算。

闭操作想将图像进行膨胀,然后对膨胀的结果进行腐蚀。闭操作用于复杂连通分支算法中减少无用或噪声驱动的片段。

对于连通分支,通常先进行腐蚀或闭操作消除噪声,然后通过开操作连接相互靠近的大型区域。

对于一幅非布尔型图像进行形态学操作时,闭操作最明显的效果是消除值小于邻域内的点的孤立异常,而开操作消除的是大于邻域内点的孤立异常值。

形态学梯度

梯度操作的结果(扩张亮域)减腐蚀操作的结果(缩减亮域)产生了原图像中的目标边缘。对于灰度图像,其结果就是计算明暗变换的趋势。形态学梯度通常用于显示明亮区域的边界,然后便可以将他们看作目标或者目标的部分。用扩张的图像减去了收缩的图像便得到完整的边界。与计算梯度不同,它并不会关注某个物体的周围。

顶帽和黑帽

顶帽用于显示与其邻近相比更亮的部分;黑帽用于显示与其邻近相比更暗的部分。

#include "stdafx.h"
#include <opencv2/opencv.hpp>int main()
{cv::namedWindow("image", cv::WINDOW_NORMAL);cv::namedWindow("erosion", cv::WINDOW_NORMAL);cv::namedWindow("dilation", cv::WINDOW_NORMAL);cv::namedWindow("opening", cv::WINDOW_NORMAL);cv::namedWindow("closing", cv::WINDOW_NORMAL);cv::namedWindow("gradient", cv::WINDOW_NORMAL);cv::namedWindow("topHat", cv::WINDOW_NORMAL);cv::namedWindow("blackHat", cv::WINDOW_NORMAL);cv::Mat img = cv::imread("D:\\personal-data\\wallpapers\\test.png");cv::Mat erosion, dilation, opening, closing, gradient, topHat, blackHat;cv::erode(img, erosion, cv::Mat());cv::dilate(img, dilation, cv::Mat());cv::morphologyEx(img, opening, cv::MORPH_OPEN, cv::Mat());cv::morphologyEx(img, closing, cv::MORPH_CLOSE, cv::Mat());cv::morphologyEx(img, gradient, cv::MORPH_GRADIENT, cv::Mat());cv::morphologyEx(img, topHat, cv::MORPH_TOPHAT, cv::Mat());cv::morphologyEx(img, blackHat, cv::MORPH_BLACKHAT, cv::Mat());cv::imshow("image", img);cv::imshow("erosion", erosion);cv::imshow("dilation", dilation);cv::imshow("opening", opening);cv::imshow("closing", closing);cv::imshow("gradient", gradient);cv::imshow("topHat", topHat);cv::imshow("blackHat", blackHat);cv::waitKey(0);cv::destroyAllWindows();return 0;
}

自定义核

在形态学上,核常常称为“构造元素”,OpenCV提供了创建自定义形态学核的函数cv::getStructuringElement()。

cv::Mat cv::getStructuringElement(int shape, cv::Size ksize, cv::Point anchor=cv::Point(-1, -1))

cv::getStructuringElement()的元素形状
形状值 元素 描述
cv::MOEPH_RECT 矩形
cv::MOEPH_ELLIPSE 椭圆形 以ksize.width和ksize.height为两个半径做椭圆
cv::MOEPH_CROSS 交叉

,当 i == anchor.y或 j == anchor.x

用任意线性滤波器做卷积

                    

上述两个核中,左边的核是可分的,右边的是不可分的。一个可分核可以理解成两个一维核,在卷积时先调用x内核,然后再调用y内核。两个矩阵进行卷积所产生的消耗可以用两个矩阵的面积之积近似。如此一来,用n×n的核对面积为A的图像进行卷积所需要的时间是,但如果分解为n×1和1×n的两个核,那么代价就是。由此可见,分解卷积核可以提高卷积计算的效率。

用cv::filter2D()进行卷积

void cv::filter2D(InputArray src, OutputArray dst, int ddepth, InputArray kernel, cv::Point anchor=cv::Point(-1, -1), double delta=0, int borderType=cv::BORDER_DEFAULT)

注:如果定义了锚点的位置,那么核的大小可以是偶数,否则必须是奇数。

通过cv::sepFilter2D使用可分核

void cv::sepFilter2D(InputArray src, OutputArray dst, int ddepth, InputArray rowKernel, InputArray  columnKernel, cv::Point anchor=cv::Point(-1, -1), double delta=0, int borderType=cv::BORDER_DEFAULT)

注:两个核的大小应当是n1×1和1×n2,n1和n2不一定相等。

生成卷积核

void cv::getDerivKernel(OutputArray kx, OutputArray ky, int dx, int dy, int ksize, bool normalize=true, int ktype=CV_32F)

作用:生成可分解核,如Sobel和Scharr核。dx和dy是求导顺序;ksize是核的大小,可以为1、3、5、7或cv::SCHARR;normalize指示是否核元素规范化,如果是浮点型图像,设为true,反之设为false;ktype表示滤波器的类型,可以使CV_32F和CV_64F。

cv::Mat cv::getGaussianKernel(int ksize, double sigma, int ktype=CV_32F)

作用:生成高斯核。

α在滤波器需要规范化的时候才起作用。sigma可以为-1,这样将自动计算,其中

OpenCV的滤波与卷积相关推荐

  1. OpenCV基础九:滤波与卷积(陆续更新)

    九. 滤波与卷积 边界外推和边界处理 自定义边框 自定义外推 阈值化操作 cv::threshold函数 double cv::threshold(cv::InputArray src,cv::Out ...

  2. 《学习OpenCV3》第10章 滤波与卷积

    <学习OpenCV3>第10章 滤波与卷积 1. 预备知识 1.1 滤波.核和卷积 1.2 边界外推和边界处理 1.2.1 自定义边框 1.2.2 自定义外推 2. 阈值化操作 2.1 t ...

  3. opencv图像滤波

    1.介绍 OpenCV图像处理技术中比较热门的图像滤波操作主要被分为了两大类:线性邻域滤波和非线性滤波.线性邻域滤波常见的有"方框滤波","均值滤波"和&quo ...

  4. opencv 对图像进行卷积

    卷积 什么是二维卷积呢?看下面一张图就一目了然: 卷积就是循环对图像跟一个核逐个元素相乘再求和得到另外一副图像的操作,比如结果图中第一个元素5是怎么算的呢?原图中3×3的区域与3×3的核逐个元素相乘再 ...

  5. 从RC低通滤波到卷积的理解

    从RC低通滤波到卷积的理解 低通滤波器(英语:Low-pass filter)容许低频信号通过,但减弱(或减少)频率高于截止频率的信号的通过.对于不同滤波器而言,每个频率的信号的减弱程度不同.当使用在 ...

  6. opencv均值滤波,方盒滤波,cv2.boxFilter,cv2blur

    均值滤波 opencv使用均值滤波是通过cv2.blur来实现的,原理十分简单,就是根据周围取平均值 下面对方法进行介绍 def blur(src, ksize, dst=None, anchor=N ...

  7. 【论文分享】联合形态学滤波和卷积稀疏编码的图像去雨

    [论文分享]联合形态学滤波和卷积稀疏编码的图像去雨

  8. 学习OpenCV 4(二)滤波与卷积

    系统 Ubuntu 18.04 OpenCV 版本 4.5.1 接口类型 C++ 安装OpenCV 点我安装 文章目录 一.阈值化操作 1.1 基本的阈值操作 1.2 Otsu算法 1.3 自适应阈值 ...

  9. opencv均值滤波_python+opencv图像处理(二十)

    领域平均滤波的方法是经常用来进行图像增强的方法.空域滤波指的是利用像素及像素邻域组成的空间进行滤波的方法.空域滤波主要是借助模板运算来进行的.模板运算中用得最多的是模板卷积,其主要步骤如下:1) 将模 ...

最新文章

  1. leetcode:2680 Remove Duplicates from Sorted Array 删除数组中的重复元素
  2. C#面向对象三大特性之二:继承
  3. 文件流导出乱码_Savespss:不使用StatTransfer也可转换dta为sav文件的利器
  4. SAP CRM Interactive Report(交互式报表)里和服务订单相关的一些字段
  5. 2021牛客暑期多校训练营5
  6. 54失败是成功之母二
  7. python十条建议_十条建议帮你提高Python编程效率
  8. CentOS 8明年正式停止维护,以后再也不会有免费的RHEL了!
  9. (转)ASP.NET中常见文件类型及用途
  10. java script 环境搭建_TypeScript环境搭建
  11. 企业如何进行数据质量评估
  12. ASP分页要用到的属性ADO CursorLocation知识补充:
  13. potplayer播放器没有声音的解决方案
  14. Linux的vi命令使用详解
  15. C语言学习7:ASCII码表及用法简介
  16. 关于SYS/BIOS
  17. 翻译程序、编译程序和解释程序的区别和联系
  18. 大二学期总结(我的机器人开发之路)
  19. 大数据精准营销应用(一)
  20. 2022T电梯修理考试题及在线模拟考试

热门文章

  1. php 函数封装上传,PHP(多)文件上传实现和函数封装
  2. Spring Cloud构建微服务架构:服务容错保护(Hystrix依赖隔离)【Dalston版】
  3. 论文浅尝 | Doc2EDAG:一种针对中文金融事件抽取的端到端文档级框架
  4. 11 操作系统第三章 内存管理 内存的基本知识 内存管理 内存空间扩充 连续分配管理方式
  5. zookeeper学习入门
  6. Spring详解(八)------事务管理
  7. Turtle库(海龟)
  8. bzoj 1731: [Usaco2005 dec]Layout 排队布局【差分约束】
  9. 洛谷 P1091 合唱队形
  10. - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender