• opencv c++ 图像形态学操作


    1、图像的形态学操作

            包括图像的腐蚀膨胀形态学梯度、顶帽、黑帽、分支主题、结构元素等操作。

            具体概念参考:(41条消息) 图像处理-形态学处理_Good@dz的博客-CSDN博客_图像处理 形态学

    1.1、膨胀

            用3×3的核去扫描二值图像,当核与图像中的前景像素(值为1的像素)有交集时,则将二值图像中对应的卷积核中心位置的像素值置为1。

            拓展:卷积核可以为任意形状(除1×1),且重置点可以选用卷积核中的任意位置,有‘交集‘就对重置点位置像素置1。

            

     1.2、腐蚀

            用3×3的核去扫描二值图像,仅当核的与前景像素有完全重合区域时,将二值图像中对应的卷积核中心位置的像素保留,其余情况下,将中心位置的像素置0。

             拓展:卷积核可以为任意形状,且重置点可以选用卷积核中的任意位置。

            

             膨胀与腐蚀的区别:膨胀只要有交集就触发,而腐蚀必须是重置点与前景像素有完全重合区域才保留

    1.3、开与闭

            开:腐蚀再膨胀,去除微小干扰块。

           

            闭:膨胀再腐蚀,填充闭合区域。

            

    1.4、形态学梯度

            基本梯度:膨胀图 - 腐蚀图

            内梯度:原图 - 腐蚀图

            外梯度:膨胀图 - 原图

            这里opencv只能直接实现基本梯度,在使用API:morphologyEx  时,调用MORPH_GRADIENT方法即可。

            内梯度、外梯度没有直接的API,一般通过已有API间接实现

    1.5、其余形态学操作

            顶帽:原图 - 开操作后的图

            黑帽:闭操作后的图 - 原图

            注:顶帽和黑帽操作用于获取图像中的微小细节

            击中击不中: 通过特定模板,仅当输入的图像中,有与模板一模一样的块时,被击中的输入图像区域才会被保留。

            使用API:morphologyEx  时,分别调用MORPH_TOPHAT 、MORPH_BLACKHAT、MORPH_HITMISS方法即可实现。

    2、API

            定义核形状

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


    shape——核的形状,可以定义矩形,十字形等形状,如下:


    ksize——大小
    anchor ——锚定点,即前文中的重置点。

     注:当设计到保留横线或竖线时,可以将核定义成1×n或者n×1的形状,从而去除其余形状的线。

    Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 1), Point(-1, -1));

            腐蚀:

    1. void cv::erode ( InputArray src,
    2. OutputArray dst,
    3. InputArray kernel,
    4. Point anchor = Point(-1,-1),
    5. int iterations = 1,
    6. int borderType = BORDER_CONSTANT,
    7. const Scalar & borderValue = morphologyDefaultBorderValue()
    8. )

             膨胀:

    1. void cv::dilate ( InputArray src,
    2. OutputArray dst,
    3. InputArray kernel,
    4. Point anchor = Point(-1,-1),
    5. int iterations = 1,
    6. int borderType = BORDER_CONSTANT,
    7. const Scalar & borderValue = morphologyDefaultBorderValue()
    8. )

            通用:

    1. void cv::morphologyEx ( InputArray src,
    2. OutputArray dst,
    3. int op,
    4. InputArray kernel,
    5. Point anchor = Point(-1,-1),
    6. int iterations = 1,
    7. int borderType = BORDER_CONSTANT,
    8. const Scalar & borderValue = morphologyDefaultBorderValue()
    9. )

    op ——形态学操作选用,如下:


    iterations——重复腐蚀和膨胀的次数。
    borderType ——边界类型
    borderValue ——Border value in case of a constant border. The default value has a special meaning. 

    3、代码

    3.1、腐蚀膨胀代码:

    1. void erode_dilate(Mat& image)
    2. {
    3. Mat gray;
    4. cvtColor(image, gray, COLOR_BGR2GRAY);
    5. Mat binary;
    6. threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
    7. namedWindow("THRESH_OTSU", WINDOW_FREERATIO);
    8. imshow("THRESH_OTSU", binary);
    9. Mat dst1, dst2;
    10. //定义核
    11. int kernel_size = 5;
    12. Mat kernel = getStructuringElement(MORPH_RECT, Size(kernel_size, kernel_size), Point(-1, -1));
    13. //腐蚀
    14. erode(binary, dst1, kernel);
    15. namedWindow("erode", WINDOW_FREERATIO);
    16. imshow("erode", dst1);
    17. //膨胀
    18. dilate(binary, dst2, kernel);
    19. namedWindow("dilate", WINDOW_FREERATIO);
    20. imshow("dilate", dst2);
    21. }

    3.2、开闭:

    1. void QuickDemo::open_close(Mat& image)
    2. {
    3. Mat gray;
    4. cvtColor(image, gray, COLOR_BGR2GRAY);
    5. Mat binary;
    6. threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
    7. namedWindow("THRESH_OTSU", WINDOW_FREERATIO);
    8. imshow("THRESH_OTSU", binary);
    9. Mat dst1, dst2;
    10. //定义核
    11. int kernel_size = 5;
    12. Mat kernel = getStructuringElement(MORPH_RECT, Size(kernel_size, kernel_size), Point(-1, -1));
    13. //开
    14. morphologyEx(binary, dst1, MORPH_OPEN, kernel, Point(-1, -1), 1, 0);
    15. namedWindow("MORPH_OPEN", WINDOW_FREERATIO);
    16. imshow("MORPH_OPEN", dst1);
    17. //闭、
    18. morphologyEx(binary, dst2, MORPH_CLOSE, kernel, Point(-1, -1), 1, 0);
    19. namedWindow("MORPH_CLOSE", WINDOW_FREERATIO);
    20. imshow("MORPH_CLOSE", dst2);
    21. }

     3.3、形态学梯度

    注:在边缘提取应用中,梯度边缘后,会再进行二值化,从而获取更好的边缘图像。

    1. void QuickDemo::shape_gradient(Mat& image)
    2. {
    3. Mat gray;
    4. cvtColor(image, gray, COLOR_BGR2GRAY);
    5. Mat g1, g2, g3;
    6. Mat dst1, dst2;
    7. int kernel_size = 7;
    8. Mat kernel = getStructuringElement(MORPH_RECT, Size(kernel_size, kernel_size), Point(-1, -1));
    9. //基本梯度
    10. morphologyEx(gray, g1, MORPH_GRADIENT, kernel, Point(-1, -1), 1, 0);
    11. //膨胀
    12. morphologyEx(gray, dst1, MORPH_DILATE, kernel, Point(-1, -1), 1, 0);
    13. //腐蚀
    14. morphologyEx(gray, dst2, MORPH_ERODE, kernel, Point(-1, -1), 1, 0);
    15. //外梯度
    16. subtract(dst1, gray, g2);
    17. //内梯度
    18. subtract(gray, dst2, g3);
    19. namedWindow("基本梯度", WINDOW_FREERATIO);
    20. imshow("基本梯度", g1);
    21. namedWindow("外梯度", WINDOW_FREERATIO);
    22. imshow("外梯度", g2);
    23. namedWindow("内梯度", WINDOW_FREERATIO);
    24. imshow("内梯度", g3);
    25. //最后再进行二值化,获取更好的边缘图像,选用基本梯度示例
    26. Mat binary;
    27. threshold(g1, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
    28. namedWindow("二值化", WINDOW_FREERATIO);
    29. imshow("二值化", binary);
    30. }

    3.4、其余形态学操作(顶帽、黑帽、击中击不中)

             

    1. void QuickDemo::other_method(Mat& image)
    2. {
    3. Mat gray;
    4. cvtColor(image, gray, COLOR_BGR2GRAY);
    5. Mat binary;
    6. threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
    7. namedWindow("二值化", WINDOW_FREERATIO);
    8. imshow("二值化", binary);
    9. Mat dst1, dst2, dst3;
    10. int kernel_size = 5;
    11. Mat kernel_1 = getStructuringElement(MORPH_RECT, Size(kernel_size, kernel_size), Point(-1, -1));
    12. //顶帽
    13. morphologyEx(binary, dst1, MORPH_TOPHAT, kernel_1, Point(-1, -1), 1, 0);
    14. namedWindow("顶帽", WINDOW_FREERATIO);
    15. imshow("顶帽", dst1);
    16. //黑帽
    17. morphologyEx(binary, dst2, MORPH_BLACKHAT, kernel_1, Point(-1, -1), 1, 0);
    18. namedWindow("黑帽", WINDOW_FREERATIO);
    19. imshow("黑帽", dst2);
    20. //击中击不中
    21. Mat kernel_2 = getStructuringElement(MORPH_CROSS, Size(kernel_size, kernel_size), Point(-1, -1));
    22. morphologyEx(binary, dst3, MORPH_HITMISS, kernel_2, Point(-1, -1), 1, 0);
    23. namedWindow("击中击不中", WINDOW_FREERATIO);
    24. imshow("击中击不中", dst3);
    25. }

     

     

     

  • 相关阅读:
    隆云通空气温湿、大气压力传感器
    Java基础篇 IO流
    面试官:如何优雅依赖多个版本的jar包?
    外贸客户来源的渠道有哪些?
    Java面试进阶指北
    ​​植物大战僵尸杂交版直装版v2.1 安卓版:全新策略塔防体验
    【Unity3D】动态路径特效
    Vue的详细教程--用Vue-cli搭建SPA项目
    【Linux升级之路】6_进程间通信
    CAPL学习之路-诊断函数
  • 原文地址:https://blog.csdn.net/lucust/article/details/128207799