繁体   English   中英

在去除噪声的同时增强 OpenCV (Java) 中的边缘

[英]Enhance edges in OpenCV (Java) while removing noise

我正在尝试在 Java 中编写一个 OpenCV 程序,该程序用手机拍摄标记的照片并在标记上找到圆形轮廓。 我已经让它在 Android 模拟器中工作(照片具有完美的照明条件),但无法让它与手机本身一起工作。 这是我要捕获的标记:

在此处输入图像描述

在使用转换为灰度、高斯模糊和 Canny 边缘检测器的组合后,我得到了这个 output:

在此处输入图像描述

如果我然后尝试在图像上找到轮廓,则返回的轮廓数量非常高(超过 1000 个),但它们并没有关闭(因为边缘似乎太弱了。在原始图像上绘制的轮廓:

在此处输入图像描述

这是我用于分段的代码:

Mat processed = new Mat(original.height(), original.width(), original.type());

Imgproc.cvtColor(original, processed, Imgproc.COLOR_RGB2GRAY);

Imgproc.GaussianBlur(processed, processed, new Size(7, 7), 0.1);

Imgproc.Canny(processed, processed,  50, 50*3, 3, false);

我尝试过调整不同的参数(阈值等),但感觉这不是理想的解决方案。 我认为必须有一种方法来增强精明检测器返回的边缘,但我自己还没有找到任何东西。

任何帮助表示赞赏!

你想要这样的东西吗?

在此处输入图像描述

噪声通常存在 - 可以减少 - 您可以使用 AdaptiveThreshold 区分圆圈,然后使用我在下面描述的方法找到圆圈。 关键是,您从相机获得的真实世界图像可能包含一大堆其他圆圈 - 所以最好找到所有圆圈。 比较它们的大小。 找出在颜色、大小和位置方面与您的标记最相似的 4 个圆圈。

一个快速的python代码来区分圆圈:

# Make a gray version
gry = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)

# Thresh
ada = cv2.adaptiveThreshold(
    gry, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2
)

# Remove noises
out = cv2.medianBlur(ada, 7)

# Invert colors (Not needed)
out = ~out

我测试了 Python 代码,它可以工作; 您可以找到 Java 或 C++ 的等效项。 我试图解释 Java 代码,但我是即时编写的,没有进行测试。 我写的 Java 代码可能有错误,但它确实明白了这一点。 稍作改动可能会奏效。 我还编写了应该将圆圈作为最后一个块的代码。 使用它很棘手,需要调整参数。

Java:

...
Imgproc.cvtColor(im, gry, Imgproc.COLOR_RGBA2GRAY);
Imgproc.adaptiveThreshold(gry, ada, 255, 
    Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 11, 2);
Imgproc.medianBlur(ada, out, 7);
...

和寻找圈子:
Java:

...
SimpleBlobDetector_Params params = new SimpleBlobDetector_Params();
params.set_filterByCircularity(true);
params.set_minCircularity(0.01f);
params.set_maxArea(50000);//important
SimpleBlobDetector detector = SimpleBlobDetector.create(params);

// List of detected points 
MatOfKeyPoint keyPoints = new MatOfKeyPoint();
detector.detect(ada, keyPoints);

// Draw circles on final image
Scalar color = new Scalar(127, 0, 255);
for (KeyPoint key: keyPoints.toList()) {
    Imgproc.circle(im, key.pt, (int) (key.size / 2.0f), color, 3/*Thickness*/);
}
...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM