• 图像求导、边缘检测、分割


    Canny边缘检测算子是一种多级检测算法。1986年由John F. Canny提出,同时提出了边缘检测的三大准则:

    1. 低错误率的边缘检测:检测算法应该精确地找到图像中的尽可能多的边缘,尽可能的减少漏检和误检。
    2. 最优定位:检测的边缘点应该精确地定位于边缘的中心。
    3. 图像中的任意边缘应该只被标记一次,同时图像噪声不应产生伪边缘。

    1.sobel算子

    Sobel导数并不是真正的导数,因为Sobel算子定义在一个离散的空间上。Sobel算子真正表示的是多项式拟合。

    Sobel(imGray,imgSobeled,-1,0,1);

    2.Priwitt滤波器

    3.Scharr滤波器:相较于Sobel精度更高

    Scharr(imGray,imScharred,-1,0,1);

    4.拉普拉斯核——真正的轮廓识别

    Laplacian(imGray,imLaped,-1,1);

     分别对应:原图,Sobel/Scharr滤波,Laplacian变换

    5.Canny边缘检测

    Canny边缘检测算法可以分为以下5个步骤:

    • 1) 高斯模糊 - GaussianBlur
    • 2) 灰度转换 - cvtColor
    • 3) 计算梯度 - Sobel/Scharr
    • 4) 非最大信号抑制
    • 5) 高低阈值输出二值图像

        Mat dx,dy;
        blur(imGray,blurImage,cv::Size(3,3));
        Scharr(blurImage,dx,CV_16S,1,0);
        Scharr(blurImage,dy,CV_16S,0,1);
        Canny(dx,dy,imCannyed,100,150);

    6.hough变换

    6.1 算法思路:

    1. 初始化参数空间,将参数空间矩阵每一个像素置0;
    2. 遍历图像当中不为0的像素点,记录所有经过该像素点直线的直线参数,将参数空间中对应该直线参数的像素值加1;
    3. 根据先验知识,分析参数矩阵,获取参数矩阵某些峰值作为检测结果。

    6.2 OpenCV接口:

    • Hough变换主要优点是能容忍特征边界描述中的间隙,并且相对不受图像噪声的影响。
    • SHT,标准hough变换
    • MHT,多尺度hough变换,对SHT的细化,精度更高
    • PPHT,渐进概率hough变换,计算直线及其延长线——只要峰值够高,只要花很少的时间即可,可大幅提高速度
    void HoughLines( InputArray image,   // image:输入图像
                     OutputArray lines,  //lines:检测到的直线(表示其实为直线参数(θ,p)集合)
                     double rho,       //rho:像素每次迭代的大小(即每一次选取像素的过程跳跃多少,一般设置为1)
                     double theta,     //theta:角度累加器的大小(即选取的直线参数θ的变化),一般为CV_PI/180
                     int threshold,    //thresold:阈值大小(即每个参数对至少经过的像素点数)   
                     double srn = 0, double stn = 0,
                     double min_theta = 0, double max_theta = CV_PI );
    

     C++程序实现参考:https://github.com/ljwcdtj/HoughTransform

    6.3 缺点

    • 巨量的计算,难以达到实时性
    • 解决思路:
    • 裁剪原始图像,缩小搜索范围
    • 平方根,正弦,余弦计算的查表化
    • “多尺度”搜索策略,即先对原图抽样数据进行粗搜索定位,再对原图在一定的角度范围内进行搜索
    • 先验知识(直线走向,长度等限制)的使用以及一些多线程/并行计算策略

    6.4 参考:https://blog.csdn.net/ljwcdtj/article/details/89091060

    7.距离变换(有标记、无标记)

    • 用于细化字符的轮廓和查找物体质心(中心)。参考:https://blog.csdn.net/z827997640/article/details/80461240

     7.1 算法思路

    按照某种距离(如:D4距离或D8距离)对大小为M×N的图像中的区域块作距离变换,算法过程如下:

    • 1、建立一个大小为M×N的数组F,作如下的初始化:将区域块中的元素设置为0,其余元素设置为无穷;
    • 2、利用掩模1(mask1),左上角开始,从左往右,从上往下遍历数组,将掩模中P点对应的元素的值作如下更新:

    • 3、利用掩模2(mask2),右下角开始,从右往左,从下往上遍历数组,将掩模中P点对应的元素的值作如下更新:

    • 4、最终得到的更新后的数组即为距离变换的结果。

    7.2 opencv接口

    void distanceTransform( InputArray src, 
                  OutputArray dst,
                            int distanceType,
                   int maskSize,
                   int dstType=CV_32F);
    
    InputArray src:输入图像,一般为二值图像;
    OutputArray dst:输出的图像,距离变换结果;
    int distanceType:用于距离变换的距离类型(欧氏距离:DIST_L2 = 2;$D_4$距离:DIST_L1 = 1;$D_8$距离:DIST_C = 3等);
    int mask_size:距离变换掩模的大小,一般为3或5;
    int dstType:输出图像的数据类型,可以为CV_8U或CV_32F。

    7.3 应用 

    • 骨架抽取
    • 用距离变换的方式来实现匹配,配合倒角距离变换(Chamfer Distance Transform)可以达到快速匹配的效果。(对旋转、缩放是无效的)

     7.4 参考:

    https://zhuanlan.zhihu.com/p/38917770

    https://www.2cto.com/kf/201701/586976.html

    8.分割

    8.1 漫水填充

    • cv::floodFill()

    8.2 分水岭算法

    • 无单独背景蒙版时,需要分割图像:图中的线转化成“山”,平坦区域转化成“谷”用以分割
    • 使用者/算法先标记对象或背景的一部分
    • cv::watershed()

    8.3 Grabcuts算法

    • 使用者/算法在待分割对象周围提供一个矩形框,其外部即为背景
    • cv::grabCut()

    8.4 Mean-shift分割

    • 基于颜色分布峰值进行分割
    • 通过滑动窗口找到最高密度块,
    • cv::pyrMeanShiftFiltering()
  • 相关阅读:
    day 05 讲解java三大特性
    day 02 运算符
    石大 6-9 待提交
    poj分类
    NLog使用总结
    VS 2010下单元测试
    MQTT----物联网常用的消息队列协议
    使用jfreechart生成柱状图、折线图、和饼状图
    JavaBean持久化
    使用maven搭建springMVC开发环境
  • 原文地址:https://www.cnblogs.com/yrm1160029237/p/11937744.html
Copyright © 2020-2023  润新知