Opencv Image Filtering 学习

来源:互联网 发布:app游戏制作软件 编辑:程序博客网 时间:2024/06/13 22:54
#include "stdafx.h"#include "ImageFiltering.h"using namespace cv;ImageFiltering::ImageFiltering(){}ImageFiltering::~ImageFiltering(){}void ImageFiltering::openCV_bilateralFilte(Mat src, Mat &dst){// 双边滤波 // 双边滤波器可以很好地减少不需要的噪声同时保持边缘的锐利。然而它的代价是速度比较慢// 双边滤波的两个sigmaColor、sigmaSpace值越大,滤波效果越明显,滤波后的图片也越像“卡通图片”// sigmaColor的值越大,就能混合邻域内像素值相差越大的像素点。// sigmaSpace 控件滤波器,值越大,邻域内的两个像素相互影响就越大。// d 滤波器的size——(d > 5)会非常慢,因此,在实时性较高时,建议size设为d = 5;d的值越大模糊效果越明显// 如果实时性不是那么高,可以将size——(d = 9)设置大一些。//  borderType 差值方式。// 注:当d大于0时,忽略sigmaSpacebilateralFilter(src,dst,9,150,0,BorderTypes::BORDER_CONSTANT);}// 归一化的均值滤波器void ImageFiltering::openCV_blur(Mat src, Mat &dst){blur(src, dst, Size(7, 7), Point(-1, -1));}// 一般性的均值滤波器void ImageFiltering::openCV_boxFilter(Mat src, Mat &dst){boxFilter(src, dst, src.depth(), Size(7, 7),Point(-1,-1),true);}void ImageFiltering::openCV_buildPyramid(Mat src, std::vector<Mat> &dst){// 对一副图像进行金字塔层积采样,采样层数由参数maxlevel决定buildPyramid(src, dst, 5);}void ImageFiltering::openCV_dilate(Mat src, Mat &dst){// 对图像进行膨胀操作// anchor 进行膨胀的锚点,默认以核的中心为锚点// kernel 膨胀的核// iterations 膨胀的次数Mat kernel = getStructuringElement(1,Size(3,3));Scalar scalar;dilate(src, dst, kernel, Point(-1, -1), 3, BorderTypes::BORDER_CONSTANT, scalar);}void ImageFiltering::openCV_erode(Mat src, Mat &dst){// 对图像进行腐蚀操作// anchor 进行腐蚀的锚点,默认以核的中心为锚点// kernel 腐蚀的核// iterations 腐蚀的次数Mat kernel = getStructuringElement(1, Size(3, 3));Scalar scalar;erode(src, dst, kernel, Point(-1, -1), 3, BorderTypes::BORDER_CONSTANT, scalar);}void ImageFiltering::openCV_filter2D(Mat src, Mat &dst, int filterCase){int arr[9];Mat kernel;switch (filterCase){case 1: // Laplace 边缘提取kernel = (Mat_<char>(3, 3) << 0, 1, 0,                          1, -4, 1,                          0, 1, 0);filter2D(src, dst, src.depth(), kernel);break;case 2: // Laplace 边缘提取kernel = (Mat_<char>(3, 3) << 1, 1, 1,                          1, -8, 1,                          1, 1, 1);filter2D(src, dst, src.depth(), kernel);break;case 3: // 横线检测kernel = (Mat_<char>(3, 3) << -1, -1, -1,   2, 2, 2, -1, -1, -1);filter2D(src, dst, src.depth(), kernel);break;case 4:// -45度检测kernel = (Mat_<char>(3, 3) << -1, -1, 2,                          -1, 2, -1,                          2, -1, -1);filter2D(src, dst, src.depth(), kernel);break;case 5:// 45度检测kernel = (Mat_<char>(3, 3) << 2, -1, -1,  -1, 2, -1,  -1, -1, 2);filter2D(src, dst, src.depth(), kernel);break;case 6:// 竖线检测kernel = (Mat_<char>(3, 3) << -1, 2, -1,  -1, 2, -1,  -1, 2, -1);filter2D(src, dst, src.depth(), kernel);break;case 7:// Sobel边缘检测——横向kernel = (Mat_<char>(3, 3) << -1, 2, -1,0, 0, 0,-1, 2, -1);filter2D(src, dst, src.depth(), kernel);break;case 8:// Sobel边缘检测——(-45度)kernel = (Mat_<char>(3, 3) << -2, -1, 0,  -1, 0, 1,  0, 1, 2);filter2D(src, dst, src.depth(), kernel);break;case 9:// Sobel边缘检测——(45度)kernel = (Mat_<char>(3, 3) << 0, 1, 2, -1, 0, 1, -2, -1, 0);filter2D(src, dst, src.depth(), kernel);break;case 10:// Sobel边缘检测——竖直kernel = (Mat_<char>(3, 3) << -1, 0, 1,  -2, 0, 2,  -1, 0, 1);filter2D(src, dst, src.depth(), kernel);break;default:break;}convertScaleAbs(dst, dst);}void ImageFiltering::openCV_GaussianBlur(Mat src, Mat &dst){// 利用指定的高斯核对图像进行卷积,支持滤波操作// ksize 指定的高斯核大小,当和大小为零时,将通过sigma计算高斯核大小// sigmaX 高斯核在X方向上的标准差// sigmaY 高斯核在Y方向上的标准差,如果sigamY等于0,那么sigmaY的值与sigmaX的值相同,// 如果两个sigma的值都为0,,那么将通过ksize来计算得到sigma的值,// 注:在使用的过程中,建议对ksize 两个sigma值都进行指定GaussianBlur(src, dst, Size(7, 7), 1.5,1.5);}void ImageFiltering::openCV_getDerivKernels(Mat src, Mat &dst){Mat matX, matY;getDerivKernels(matX, matY, 2, 2, 7);sepFilter2D(src, dst, src.depth(), matX, matY);}void ImageFiltering::openCV_getGaborKernel(Mat src, Mat &dst){// ksize 高斯滤波核的大小// sigma 高斯包络线的标准差// theta Gabor滤波核中平行条带的方向,有效值为从0~360度的实数// lambd Gabor核函数中余弦函数的波长参数,有效值应大于2,以像素为单位,值越大找到的特征越多// gamma 空间长宽比,,值越大,找到的边缘越长,小的边缘将会被忽略Mat kernel = getGaborKernel(Size(3, 3), 1.8, 180, 3, 1);filter2D(src, dst, src.depth(), kernel);}void ImageFiltering::openCV_getGaussianKernel(Mat src, Mat &dst){// 生成一个高斯核,在用filter2D函数进行滤波跟直接调用GaussianBlur的效果是一样的。Mat kernel = getGaussianKernel(3, 0.8);filter2D(src, dst, src.depth(), kernel);}void ImageFiltering::openCV_getStructuringElement(Mat src, Mat &dst){// 获取用于形态学操作的核Mat kernel = getStructuringElement(MorphShapes::MORPH_ELLIPSE, Size(11, 11));dilate(src, dst, kernel);}void ImageFiltering::openCV_Laplacian(Mat src, Mat &dst){// 当 ksize 等于1时,Laplacian的处理效果跟openCV_filter2D的Case 1相同,// 当ksize等于3事,处理效果跟openCV_filter2D的Case 2 相同。// 由此可知,Laplacian变换其实就是利用一个特定的核,对图像进行卷积实现的。Laplacian(src, dst, src.depth(), 3);}void ImageFiltering::openCV_medianBlur(Mat src, Mat &dst){// 中值滤波:以(x,y)为中心,以ksize为半径,计算里面的中间值,利用该值替代该点的值// 中值滤波对椒盐噪声有明显的抑制作用,在此基础上,还可以演化出再大值和最小值滤波。medianBlur(src, dst, 3);}void ImageFiltering::openCV_morphologyEx(Mat src, Mat &dst, int iCase){// 形态学的各种操作,包括膨胀、腐蚀、开运算、闭运算、底帽和礼帽变换Mat kernel = getStructuringElement(MorphShapes::MORPH_RECT, Size(3, 3));Mat _src;threshold(src, _src, 50, 255, ThresholdTypes::THRESH_BINARY);switch (iCase){case 1:morphologyEx(_src, dst, MorphTypes::MORPH_DILATE, kernel);break;case 2:morphologyEx(_src, dst, MorphTypes::MORPH_ERODE, kernel);break;case 3:morphologyEx(_src, dst, MorphTypes::MORPH_CLOSE, kernel);break;case 4:morphologyEx(_src, dst, MorphTypes::MORPH_OPEN, kernel);break;case 5:morphologyEx(_src, dst, MorphTypes::MORPH_BLACKHAT, kernel);break;case 6:morphologyEx(_src, dst, MorphTypes::MORPH_TOPHAT, kernel);break;case 7:morphologyEx(_src, dst, MorphTypes::MORPH_GRADIENT, kernel);break;case 8:morphologyEx(_src, dst, MorphTypes::MORPH_HITMISS, kernel);break;default:break;}}void ImageFiltering::openCV_pyrDown(Mat src, Mat &dst){// 金字塔层积采样:向下,可以改变图像的尺寸// 主要信息不会丢失,但是会对图像细节造成模糊效果pyrDown(src, dst);}void ImageFiltering::openCV_pyrMeanShiftFiltering(Mat src, Mat &dst){// 主要用来对彩色图像进行处理:均值漂移算法// 颜色域半径sp对结果的影响比空间域半径sr对结果的影响大// sp和sr越小,细节保留得越多,sp和sr越大,平滑力度越大,同时算法消耗的时间越多// 利用该算法进行分割时,可以结合floodFile一起使用,达到图像分割的目的pyrMeanShiftFiltering(src, dst, 20, 20);}void ImageFiltering::openCV_pyrUp(Mat src, Mat &dst){// 金字塔层积采样:向上,可以改变图像的尺寸// 主要信息不会丢失,但是会对图像细节造成模糊效果pyrUp(src, dst);}void ImageFiltering::openCV_Scharr(Mat src, Mat &dst){// dx,dy 分别表示对x和y方向进行差分运算,者有利于用于检测竖直和横向的边缘特征// 检测竖向特征时,dx =1,dy=0,检测横向直线时:dx=0,dy =1Scharr(src, dst, src.depth(), 1, 0);}void ImageFiltering::openCV_sepFilter2D(Mat src, Mat &dst){// 可分离滤波器: 可以分离为x 方向和 y 方向两个独立的 1 维滤波器// 可以设置任意的滤波核对图像进行滤波处理,分别对x方向或者y方向进行滤波,或者同时进行// 大大地展现了滤波的灵活性// 如果是一个高斯滤波器,那么最后的处理效果跟GaussianBlur是一样的 Mat kernel = cv::getGaussianKernel(7, 1.5, CV_32F);sepFilter2D(src, dst, src.depth(), kernel, kernel, Point(-1, -1), 0, BORDER_DEFAULT);}void ImageFiltering::openCV_Sobel(Mat src, Mat &dst, bool bMark){if (bMark){Sobel(src, dst, src.depth(), 1, 1,3);}else{Sobel(src, dst, src.depth(), 1, 0,CV_SCHARR);}}void ImageFiltering::openCV_spatialGradient(Mat src, Mat &dstX, Mat &dstY){// 用Sobel运算符计算x和y中的一阶图像导数// 等效于:Sobel( src, dx, CV_16SC1, 1, 0, 3 );//Sobel(src, dy, CV_16SC1, 0, 1, 3);// 注:输入必须是1个通道的图像spatialGradient(src, dstX, dstY,3, 4);}void ImageFiltering::openCV_sqrBoxFilter(Mat src, Mat &dst){// 计算与过滤器重叠的像素值的标准化平方和// size 越大,丢失的细节越多sqrBoxFilter(src, dst, src.depth(), Size(11, 11));}


原创粉丝点击