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
publicstatic Mat cannyEdges(Mat img)
return
{
Mat canny =
new Mat();
Imgproc.Canny(img,canny,
30,
100);
return
canny;
}
Canny 边缘检测
原始图像
Canny 边缘检测
双边滤波图像上的 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等。
publicstatic Mat convertToBinary(Mat img)
return
{
Mat binImg =
new Mat();
Imgproc.threshold(img,binImg,
125 ,
255,Imgproc.THRESH_BINARY);
return
binImg;
}
图像转换为二进制
二进制图像
寻找轮廓: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:去除冗余点并压缩轮廓;例如:对于一条线,存储两个端点。
publicstaticvoidfindAndDrawContours(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 - 边界线的厚度。
轮廓
使用轮廓进行形状检测:我们可以使用轮廓来根据近似曲线中的周长、面积和阵列点的数量来检测形状。ImgProc 类提供了一个approxPolyDP方法,该方法返回基于轮廓的近似曲线并使用以下参数:
- curve:MatOfPoint2f
- approxCurve: MatOfPoint2f - 输出曲线
- epsilon: double - Epsilon 指定近似精度。这是原始曲线与其近似值之间的最大距离,我们可以使用 ImgProc arcLength 方法(返回曲线长度或周长)进行优化。
- closed:布尔值 - 如果近似曲线是闭合的,则为 true,否则为 false。
publicstaticvoidshapeDetection(Mat binImg,Mat org)
for
double
long
//Detecting Rectangle Shape
if
double
//rectangle with area greater than 500
if
{
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();
}
使用轮廓进行形状检测
最新评论
推荐文章
作者最新文章
你可能感兴趣的文章
Copyright Disclaimer: The copyright of contents (including texts, images, videos and audios) posted above belong to the User who shared or the third-party website which the User shared from. If you found your copyright have been infringed, please send a DMCA takedown notice to [email protected]. For more detail of the source, please click on the button "Read Original Post" below. For other communications, please send to [email protected].
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。