page contents

Java中的OpenCV-图像处理教程

本文讲述了Java中的OpenCV-图像处理教程!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

attachments-2023-08-ZolD4EVM64dad3a18b577.png本文讲述了Java中的OpenCV-图像处理教程!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

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

Canny 边缘检测

轮廓和形状识别

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

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

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

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

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

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

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

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

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 边缘检测

attachments-2023-08-L1Xw2HDi64dad2bb7aa83.png

原始图像

attachments-2023-08-rWjsFIhP64dad2d27c582.png

Canny 边缘检测

attachments-2023-08-9kJE0cwd64dad2fe13d39.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 提供不同类型的阈值技术,如OTSU、TOZERO等。

public static Mat convertToBinary(Mat img){

        Mat binImg = new Mat();

        Imgproc.threshold(img,binImg,125 ,255,Imgproc.THRESH_BINARY);

        return binImg;

}

图像转换为二进制

attachments-2023-08-DxRyEgQj64dad31bce37c.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 - 边界线的厚度。

attachments-2023-08-bzKyfOw264dad346863e5.png

轮廓

使用轮廓进行形状检测:我们可以使用轮廓来根据近似曲线中的周长、面积和阵列点的数量来检测形状。ImgProc 类提供了一个approxPolyDP方法,该方法返回基于轮廓的近似曲线并使用以下参数:

curve:MatOfPoint2f

approxCurve: MatOfPoint2f - 输出曲线

epsilon: double - Epsilon 指定近似精度。这是原始曲线与其近似值之间的最大距离,我们可以使用 ImgProc arcLength 方法(返回曲线长度或周长)进行优化。

closed:布尔值 - 如果近似曲线是闭合的,则为 true,否则为 false。

public static void shapeDetection(Mat binImg,Mat org){

        List<MatOfPoint> contourList = new ArrayList<MatOfPoint>();

        List<MatOfPoint> selectedContours = new ArrayList<>();

        Imgproc.findContours(binImg,contourList,new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

        for(int i=0;i<contourList.size();i++){

            MatOfPoint2f point = new MatOfPoint2f();

            point.fromList(contourList.get(i).toList());

            MatOfPoint2f approxCurve = new MatOfPoint2f();

            double parameter = Imgproc.arcLength(point, true);

            Imgproc.approxPolyDP(point, approxCurve, parameter * 0.02, true);

            long total = approxCurve.total();

            //Detecting Rectangle Shape

            if (total == 4) {

                double area = Imgproc.contourArea(contourList.get(i));

                //rectangle with area greater than 500

                if(area>500)

                selectedContours.add(contourList.get(i));

            }

        }

        Imgproc.drawContours(org, selectedContours, -1, new Scalar(50, 205, 50), 3);

        HighGui.imshow("Contours",org);

        HighGui.waitKey();

    }

使用轮廓进行形状检测

attachments-2023-08-OrDlMacM64dad365d4fb0.png

更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

想高效系统的学习Java编程语言,推荐大家关注一个微信公众号:Java圈子。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Java入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2023-03-2AoKIjPQ64014b4ad30a3.jpg

  • 发表于 2023-08-15 09:23
  • 阅读 ( 154 )
  • 分类:Java开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
小柒
小柒

1470 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1470 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章