基本opencv2处理方法(三)-基本滤波器

滤波是图像处理中的一个基本操作。滤波去除图像中的噪声,提取感兴趣的特征,允许图像重采样。

图像中的频率和空域:空间域指用图像的灰度值来描述衣服图像,而频域指用图像灰度值的变化来描述一幅图像。
低通滤波器和高通滤波器的概念是在频率中产生的。低通滤波器指去除图像中的高频成分,而高通滤波器指去除图像中的低频成分。

  • 低通滤波器
    Mat image = imread("1.jpg",1); 
    Mat result;

    blur(image,result,Size(5,5));//模板大小 5*5
    namedWindow("均值滤波");
    imshow("均值滤波",result);


    GaussianBlur(image,result,Size(7,7),1.5);//1.5 是sigma系数
    namedWindow("高斯滤波");
    imshow("高斯滤波",result);

低通滤波器的效果是对图像进行模糊和平滑,减弱了物体边缘可见的快速变化。它是一种线性滤波器,原理是与核进行卷积运算,此时的核是内定的。如果你需要自定义核,我们就可以使用filter2D指定 Mask模板。

  • 中值滤波器是非线性滤波器,它的原理是计算Mask模板中的中值,并用中值替换当前的像素值,因此对于去除椒盐噪声非常有用。
    medianBlur(image,result,5);// 5 是ksize
    namedWindow("中值滤波");
    imshow("中值滤波",result);
  • 方向滤波器-Sobel算子
    Sobel算子就是通过卷积操作来计算图像的一阶导数,由于边缘图像灰度变化率较大,因此可以用Sobel算子来进行边缘检测。Sobel算子的核定义为:
    基本opencv2处理方法(三)-基本滤波器_第1张图片

y方向可以这么记:
下减上。 在模板中的第三行减去第一行,就是求导了。
x方向同理。右减左。


Sobel(InputArray src, OutputArray dst, int ddepth,int dx, int dy, int 
ksize=3,doublescale=1, double delta=0,int borderType=BORDER_DEFAULT );

ddepth为图像类型,(dx,dy) = (1,0)为x方向导数,(dx,dy) = (0,1)为y方向导数。 scale和delta的作用是在对图像保存前可以对图像进行缩放操作。
即为dst = dst*scale+delta;
示例代码如下:

    Mat sobel_x;
    image = imread("1.jpg",1); 
    Sobel(image,sobel_x,CV_8U,1,1,3);
    namedWindow("sobel滤波");
    imshow("sobel滤波",sobel_x);
  • 拉普拉斯变换:
    拉普拉斯变化时基于图像导数的高通滤波器,计算二阶导数以衡量图像的弯曲度。

    Mat matLaplacian;
    image = imread("1.jpg",1); 
    Laplacian(image,matLaplacian,CV_16S,3);

//Laplacian(image,matLaplacian,CV_16S,3);或者直接CV_16S类型,这样不需要进行转变,但是此时计算的值会失去精度

    matLaplacian = abs(matLaplacian);//二阶导数肯定含有负数
    matLaplacian.convertTo(matLaplacian,CV_8U);

    namedWindow("拉普拉斯");
    imshow("拉普拉斯",matLaplacian);

Sobel算子和拉普拉斯变换可以进行边缘检测,但是这样的二值边缘图像有两个缺点:第一,检测到的边缘过粗,这意味着难以实现物体的精确定位。第二,难以找到这样的阈值,即能够检测到所有重要的边缘,同时不至于包含过多次要的边缘。

  • Canny算子
    canny算子基于sobel算子,有两个阈值。这样可以得到两幅边缘图。canny算法组合这两幅边缘图生成一幅最优的轮廓图。如果存在连续的边缘点,则将低阈值图像中的边缘点与高阈值图像中的边缘相连接,那么就保留低阈值图像中的边缘点。这种使用双阈值以得到二值图像的策略被称为瓷质阈值化。

高斯滤波器的大小:第一步所用的平滑滤波器将会直接影响 Canny 算法的结果。opencv中没有这个参数的设定,matlab中有。

  • 提取连通区域轮廓
    连通区域指的是二值图像中相连像素组成的形状。
    提取轮廓的简单算法如下:
    系统性地扫描图像直到遇到连通区域的一个点,以他为起始点,跟踪他的轮廓,标记边界上的的像素。当轮廓完整闭合,扫描回上一个位置,直到再次发现新的区域成分部分。
    Mat bw;
    image = imread("1.jpg",0); 
    threshold(image,bw,100,255,THRESH_BINARY);//进行二值化

    vector<vector> contours;

    findContours(bw,contours,CV_RETR_CCOMP,CV_CHAIN_APPROX_NONE,Point(0,0));

    //可以进一步处理 移除过小或过大的轮廓
    int cmin = 100;
    int cmax = 1000;

    vector<vector>::const_iterator itc = contours.begin();
    while (itc!=contours.end())
    {
        if (itc->size()size()>cmax)
        {
            itc = contours.erase(itc); //这个是STL中的技术点,删除元素后一定要记住返回的迭代器值,因为删除后,
            //原始迭代器的值就立刻失效了,返回的才是一个有效迭代器
        }
        else itc++;

    }

    Mat conresult(image.size(),CV_8U,Scalar(255));
    drawContours(conresult,contours,-1,Scalar(0),2);
    namedWindow("轮廓");
    imshow("轮廓",conresult);
  • Hough变换
    Hough变换的原理其实比较好理解,它是基于一个投票阈值的。拿hough直线检测为例,将一个点参数化为另一个坐标系。在另一个坐标系中多条直线如果相交于一点超过了设置的投票阈值,那么这些点就是在一条直线上。

    //原始hough变换
    Mat image = imread("1.jpg",0); 
    Mat result;
    Canny(image,result,150,220);
    vector lines;
    HoughLines(result,lines,1,3.1415926/180,50);
    for (size_t i =0;ifloat rho = lines[i][0],theta = lines[i][1];
        Point pt1(rho/cos(theta),0),pt2((rho-result.rows*sin(theta))/cos(theta),result.rows); 
        line(image,pt1,pt2,Scalar(255),3,CV_AA);
    }
    namedWindow("基本hough");
    imshow("基本hough",image);

houghlines的计算效率比较低O(n*n*m),耗时较长,而且没有检测出直线的端点。概论霍夫直线检测houghlinesP是一个改进,不仅执行效率较高,而且能检测到直线的两个端点。
houghlinesP不是系统的进行扫描图像,而是随机挑选像素点,一旦累加器中某一项达到给定的最小值,那么扫描沿着对应像素并移除所有经过的像素点。得到的是一条线段。会将一条直线(表示为x0,y0,x1,y1)放入vector中。

    image = imread("1.jpg",0); 
    vector linesHoughP;
    HoughLinesP(result,linesHoughP,1,3.1415926/180,50,50,10);//最小投票为50(直线上的点不少于50),线条不短于50,间隙不小于10 
    for (size_t i =0;i0],I[1]),Point(I[2],I[3]),Scalar(255),3,CV_AA);
    }
    namedWindow("概念hough");
    imshow("概念hough",image);

其实hough变换理论可以检测任何可以使用参数表示的图形,比如常用的还有hough圆检测,类似。

vector circles;
HoughCircles(result,circles,CV_HOUGH_GRADIENT,
2,//累加器的分辨率
50,//两个圆之间的最小距离
200,//canny高阈值
100,//最小投票数
);

HoughCircles整合了canny检测和hough变换。

你可能感兴趣的:(计算机视觉与机器学习)