java - OpenCV - 用二进制垫上的线条细化会导致随机水平虚线
问题描述
我正在编写一种从二进制图像(背景为黑色)中细化白线的方法。本质上,代码循环遍历图像并找到同一行中的连续白色像素,将它们全部变为黑色,最后将中间的像素变为白色。该算法可以很好地细化线条,但会在根本不应该有任何东西的地方产生随机的水平虚线。下面是一个例子:
显然,图像顶部和底部附近的虚线不应该存在,因为原始图像中没有白色区域,但不知何故它们是生成的。我附上了我的代码来做下面的细化,非常感谢任何帮助!
//Line thining
double[] rgbCanny;
int inARow = 0;
for(int i = 0; i < noiseReducedCanny.size().height; i++) {
for(int j = 0; j < noiseReducedCanny.size().width; j++) {
rgbCanny = noiseReducedCanny.get(i, j);
if(rgbCanny[0] == 255) {
inARow++;
} else {
if(inARow != 0 && inARow % 2 == 1) {
int middle = (int) Math.ceil(j - inARow / 2.0);
for(int x = j - inARow; x < j; x++) {
noiseReducedCanny.put(i, x, new double[]{0, 0, 0});
}
noiseReducedCanny.put(i, middle, new double[]{255, 255, 255});
} else if (inARow != 0 && inARow % 2 == 0) {
int middle = j - inARow / 2;
for(int x = j - inARow; x < j; x++) {
noiseReducedCanny.put(i, x, new double[]{0, 0, 0});
}
noiseReducedCanny.put(i, middle, new double[]{255, 255, 255});
}
inARow = 0;
}
}
}
解决方案
请注意,即使算法似乎有效,您的线条也不是 1 像素宽。它们是 3 像素宽。
显然put()
是设置 3 个连续的白色像素,从给定的索引 ( middle
) 开始。2 个意外像素导致您的算法“反馈”到自身,这意味着它们正在触发inARow++
线路。
我不是 OpenCV 人,而且我无法轻松put()
找到mat
. 然而,似乎有可能改变这一点:
new double[]{255, 255, 255}
对此:
new double[]{255}
将导致所需的行为。
您可能还想修复“黑化”线。
推荐阅读
- vuejs2 - VueJS State Getter 正在寻找匹配项,但未返回正确的值
- java - 使用格式说明符
- android - 空文档的 Android Firestore id
- java - 仅在 CLI 上的单元测试中无法在 src/main/resources 中找到 xsd
- iot - 总是从服务器获得 -1 连接被拒绝响应
- c++ - 使用 WMI 和 C++ 获取主板序列号时出现问题
- flutter - 适用于 iOS 的自定义 Flutter 插件开发
- rust - 如何从底层的子树中获取 roothash 或证明?
- discord - Discord.js 如果有角色则发送消息
- javascript - 如何重置 Impetus.js 的动量?