一、概述
在Java环境下实现Sobel边缘检测提供了便利。
通过JavaCV,我们可以轻松地将Sobel边缘检测算法应用到各种图像处理项目中,充分发挥其优势。在图像处理领域,边缘检测是一项至关重要的任务。图像中的边缘包含了丰富的信息,例如物体的轮廓、区域的边界等。边缘检测算法有多种,其中 Sobel边缘检测算法 以其精确性和可靠性而备受关注。Sobel边缘检测算法的目标是在尽可能减少噪声影响的同时,准确地检测出图像中的边缘。
二、JavaCV环境配置
在使用JavaCV之前,需要先配置开发环境。
可以通过Maven引入JavaCV的依赖,或者手动下载Jar包。
以下是Maven依赖添加示例:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>3d</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.9</version>
</dependency>
</dependencies>
</project>
三、索贝尔算子原理
Sobel算子是一阶导数的边缘检测算子,在算法实现过程中,通过3×3模板作为核与图像中的每个像素点做卷积和运算,然后选取合适的阈值以提取边缘。
一个特殊卷积所实现的功能是由卷积核的形式决定的。这个核本质上是一个大小固定、由数值参数构成的数组,数组的参考点(anchor point)通常位于数组的中心。数组的大小成为核支撑。单就技术而言,核支撑实际上仅仅由核数组的非0部分组成。对图像的卷积,首先将核的参考点定位到图像的第一个像素点,核的其余元素覆盖图像中其相对应的局部像素点。对于每一个核点,我们可以得到这个点的核值以及图像中相应图像点的值,将这些值相乘并求和,并将这个结果放在与输入图像参考点所相对应的位置。通过在整个图像上扫描卷积核,对图像的每个点重复此操作。
索贝尔算子(Sobel operator)主要用作边缘检测,在技术上,它是一阶离散性差分算子,用来运算图像亮度函数的灰度值近似值。在图像的任何一点使用此算子,将会产生对应的灰度矢量或是其法矢量。
Sobel卷积因子为:
四、代码实现
package com.test;
import org.bytedeco.javacv.CanvasFrame;
import org.bytedeco.javacv.OpenCVFrameConverter;
import org.bytedeco.opencv.global.opencv_core;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.opencv_core.*;
import static org.bytedeco.opencv.global.opencv_core.*;
import static org.bytedeco.opencv.global.opencv_imgcodecs.imread;
import static org.opencv.core.CvType.CV_16S;
//Sobel 通过计算图像梯度(水平和垂直方向)检测边缘。
public class ImageEdgetSobel {
public static void main(String[] args) {
// 加载图像
Mat image = imread("/Users/csguo007/Desktop/images.jpeg");
// 检查图像是否正确加载
if (image.empty()) {
System.out.println("Error loading image!");
return;
}
//图片灰度处理
Mat gray = new Mat();
opencv_imgproc.cvtColor(image, gray, opencv_imgproc.COLOR_BGR2GRAY); // 转换为灰度图,因为边缘检测通常在灰度图上进行
// 1. 计算X和Y方向的梯度
Mat gradX = new Mat(), gradY = new Mat(), absGradX = new Mat(), absGradY = new Mat();
opencv_imgproc.Sobel(gray, gradX, CV_16S, 1, 0, 3, 1, 0, BORDER_DEFAULT);
opencv_imgproc.Sobel(gray, gradY, CV_16S, 0, 1, 3, 1, 0, BORDER_DEFAULT);
// 2. 转换到8UC1格式
opencv_core.convertScaleAbs(gradX, absGradX);
opencv_core.convertScaleAbs(gradY, absGradY);
//边缘,合并梯度
Mat edges = new Mat();
opencv_core.addWeighted(absGradX, 0.5, absGradY, 0.5, 0, edges);
// 4. 创建一个窗口,显示结果
CanvasFrame canvasFrame = new CanvasFrame("Image Display");
canvasFrame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
canvasFrame.showImage(new OpenCVFrameConverter.ToMat().convert(edges));
}
}
五、学习资源
更多学习资料,欢迎加入我们