五、平滑处理与轮廓提取

(一)平滑处理

1、高斯滤波器(个人感觉是最有用的)

函数:

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

  • src – 输入图片
  • dst – 输出图片
  • ksize – 高斯内核大小。ksize.width和ksize.height允许不相同但他们必须是正奇数。或者等于0,由参数sigma的乘机决定。
  • X – 高斯内核在X方向的标准偏差。
  • Y – 高斯内核在Y方向的标准偏差。如果sigmaY为0,他将和sigmaX的值相同,如果他们都为0,那么他们由ksize.width和ksize.height计算得出。
  • borderType – 用于判断图像边界的模式。
#include
#include
using namespace std;
using namespace cv;
int main() {
	Mat image;
	image = imread("D://RM//OpenCv的学习//平滑处理与轮廓提取//平滑处理//11.jpg");
	imshow("原图", image);
	Mat dst;
	GaussianBlur(image, dst, Size(5, 5), 15);
	imshow("高斯模糊", dst);


	waitKey(0);
	return 0;
}

五、平滑处理与轮廓提取_第1张图片

2、中值滤波器:

函数: medianBlur (InputArray  src, OutputArray  dst, int  ksize )

直接干代码:

#include
#include
using namespace std;
using namespace cv;
int main() {
	Mat image;
	image = imread("D://RM//OpenCv的学习//平滑处理与轮廓提取//平滑处理//11.jpg");
	imshow("原图", image);
	Mat dst;
	medianBlur(image, dst, 5);
	imshow("中值模糊", dst);

	waitKey(0);
	return 0;
}

结果:

五、平滑处理与轮廓提取_第2张图片

3、双边处理

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

参数解释

1)src – 源必须是8位或者浮点数,1或者3通道图片。

2)dst – 输出图片,和输入图片相同大小和深度。

3)d – 在滤波过程中使用的各像素邻域直径,如果这是一个非整数,则这个值由sigmaSpace决定。

4)sigmaColor – 颜色空间的标准方差。数值越大,意味着越远的的颜色会被混进邻域内,从而使更大的颜色段获得相同的颜色。

5)sigmaSpace – 坐标空间的标注方差。 数值越大,以为着越远的像素会相互影响,从而使更大的区域足够相似的颜色获取相同的颜色。当d>0,d指定了邻域大小且与sigmaSpace无关。否则,d正比于sigmaSpace。

为什么运行后的图像与原来没有区别?

(二)轮廓提取

1、findContours发现轮廓

findContours(
InputOutputArray  img,
OutputArrayOfArrays  contours,//输出找到的轮廓对象
OutputArray,  hierachy// 图像的拓扑结构
int mode, //轮廓返回的模式
int method,//发现方法
Point offset=Point()//轮廓像素的位移(默认没有位移(0, 0))
)

 

2、drawContours绘制轮廓

drawContours(
InputOutputArray  img, // 输出图像
 OutputArrayOfArrays  contours,//找到的全部轮廓对象
Int contourIdx//轮廓索引号
const Scalar & color,//绘制颜色
int  thickness,//绘制线宽
int  lineType ,//线的类型(默认8)
InputArray hierarchy,//拓扑结构图
int maxlevel,//最大层数(0只绘制当前的,1表示绘制绘制当前及其内嵌的轮廓)
Point offset=Point()//轮廓位移
)

代码

#include
#include
using namespace std;
using namespace cv;
int main()
{
    Mat src, dst;
    src = imread("D://RM//OpenCv的学习//平滑处理与轮廓提取//轮廓提取//55.jpg");
    if (src.empty())
    {
        printf("can not load image \n");
        return -1;
    }
    namedWindow("input", WINDOW_AUTOSIZE);
    imshow("input", src);
    dst = Mat::zeros(src.size(), CV_8UC3);

    blur(src, src, Size(3, 3));
    cvtColor(src, src, COLOR_BGR2GRAY);
    Canny(src, src, 20, 80, 3, false);
    std::vector> contours;
    std::vector hierarchy;
    findContours(src, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));

    RNG rng(0);//随机数函数
    for (int i = 0; i < contours.size(); i++)
    {
        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));//这个函数是产生一个随机的颜色
        drawContours(dst, contours, i, color, 2, 8, hierarchy, 0, Point(0, 0));
    }
    namedWindow("output", WINDOW_AUTOSIZE);
    imshow("output", dst);
    waitKey();
    return 0;
}

上述代码部分解释:

Canny()函数  :输入图像进行边缘检测。
void Canny(    InputArray image, 
            OutputArray edges,
            double threshold1, 
            double threshold2,
            int apertureSize = 3, 
            bool L2gradient = false);
第一个参数:输入图像(八位的图像)
第二个参数:输出的边缘图像
第三个参数:下限阈值,如果像素梯度低于下限阈值,则将像素不被认为边缘
第四个参数:上限阈值,如果像素梯度高于上限阈值,则将像素被认为是边缘(建议上限是下限的2倍或者3倍)
第五个参数:为Sobel()运算提供内核大小,默认值为3
第六个参数:计算图像梯度幅值的标志,默认值为false

五、平滑处理与轮廓提取_第3张图片

 

五、平滑处理与轮廓提取_第4张图片

你可能感兴趣的:(opencv,C++)