Java中的OpenCV-图像处理

7c20c3b44b53ceb6527f364764e0f907.jpeg

我们将在本文中介绍以下高级图像处理操作:

  • Canny 边缘检测

  • 轮廓和形状识别

Canny 边缘检测:Canny 边缘检测是一种流行的边缘检测算法。它是由 John F. Canny 在 1986 年开发的。它是一个多阶段算法,我们将按如下方式经历每个阶段:

  1. 噪声抑制:第一步是使用高斯平滑从图像中去除噪声,这涉及使用高斯核,其中靠近核中心的像素被赋予比远处像素更多的权重。

  2. 梯度计算:应用Sobel 滤波器计算图像的梯度以计算边缘强度和方向,该滤波器突出显示 x 和 y 轴上的强度变化。

  3. Non-Maximum Suppression: Non-Maximum Suppression通过遍历上一步生成的梯度矩阵中的所有值来寻找边缘方向强度更大的像素,从而减少边缘的厚度。

  4. 双阈值滞后:最后一步使用输入参数下阈值和上限阈值来过滤掉潜在边缘,根据以下标准丢弃不相关的边缘:

    如果像素梯度值高于上限阈值,则像素被接受为边缘。

    如果像素梯度值低于下限阈值,则像素被拒绝。

    如果像素梯度值介于两个阈值之间,则仅当它连接到高于阈值上限的像素时才会被接受。

ImgProc类为 Canny 边缘检测提供了一个Canny方法,该方法采用以下参数:

  • Source Image: Mat

  • Output edges: Mat

  • Lower Threshold: double

  • Upper Threshold: double

public static Mat cannyEdges(Mat img){
        Mat canny = new Mat();
        Imgproc.Canny(img,canny,30,100);
        return canny;
    }

Canny 边缘检测

01c8b5ee35a26e91a24e4322e058159b.png

原始图像

1fd926e16f29b45654deca84be481842.png

Canny 边缘检测

9575b48e01f764b8301e902ca7d88d95.png

双边滤波图像上的 Canny 边缘检测

注意:Canny 边缘检测算法基于梯度,因此对图像噪声高度敏感。因此,在灰度图像上应用 Canny 边缘检测是一种很好的做法。

轮廓:轮廓可以定义为连接沿边界具有相同强度的所有连续点的曲线。它们对于形状分析和对象检测很有用。

使用二值图像查找轮廓是一种很好的做法。二值图像是这样的图像,其中每个像素只能有两个可能的强度值(0 表示黑色,1 或 255 表示白色)。

ImgProc 类提供了一种用于生成二值图像的阈值方法,该方法使用以下参数:

  • Source Image: Mat – grayscale image

  • Output Image: Mat

  • Threshold : double: 如果像素值小于阈值,则设置为 0。

  • Maximum:双精度 – 分配给超过阈值的像素的最大值。

  • Type of threshold:int – OpenCV 提供不同类型的阈值技术,如OTSUTOZERO等。

public static Mat convertToBinary(Mat img){
        Mat binImg = new Mat();
        Imgproc.threshold(img,binImg,125 ,255,Imgproc.THRESH_BINARY);
        return binImg;
}

图像转换为二进制

9e06a3969c80fd794c212c7cca5f91ef.png

二进制图像

寻找轮廓:ImgProc 类提供了一个findContours方法,该方法接受以下输入参数:

  • Image:Mat  – 二进制图像

  • Contours : List- 检测到的轮廓存储在这个列表中

  • Hierarchy : Mat – 存储有关图像拓扑的信息

  • Contour Retrieval Mode:int – OpenCV 提供以下检索模式:

    • **RETR_LIST(0)**:检索所有轮廓而不保持层次关系。

    • RETR_EXTERNAL(1): 仅检索所有极端外轮廓。

    • RETR_CCOMP(2): 检索所有轮廓并将它们排列到 2 级层次结构中。对象的外部轮廓放置在层次 1 中,对象内部的孔的轮廓放置在层次 2 中。

    • RETR_TREE(3): 检索所有轮廓并创建完整的层次结构列表。

  • Contour Approximation Method : int – 近似方法指定存储边界坐标的方式。

    • CHAIN_APPROX_NONE:存储所有边界点。

    • CHAIN_APPROX_SIMPLE:去除冗余点并压缩轮廓;例如:对于一条线,存储两个端点。

public static void findAndDrawContours(Mat binImg,Mat org){
        List<MatOfPoint> contourList = new ArrayList<MatOfPoint>();
        Imgproc.findContours(binImg,contourList,new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
        Imgproc.drawContours(org, contourList, -1, new Scalar(50, 205, 50), 2);
        HighGui.imshow("Contours",org);
        HighGui.waitKey();
}

查找和绘制轮廓

绘制轮廓: ImgProc 类提供了一个drawContours方法,该方法使用以下参数:

  • Image:Mat  – 目标图像

  • Contour List:List< MatOfPoint>

  • Contour Index: int – 要绘制的轮廓索引,负值表示所有轮廓都已绘制。

  • Color:Scalar  – 轮廓的颜色。

  • Thickness:int – 边界线的厚度。

f827a81bf9d2728ed33824f515f1bcbb.png

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2023年2月25日
下一篇 2023年2月25日

相关推荐