我正在写一种方法来从二进制图像(背景为黑色)中细化白线。本质上,代码循环遍历图像并找到同一行中的连续白色像素,将所有像素都变黑,最后将中间像素变白。该算法可以很好地使线条变细,但会在根本不存在任何东西的地方生成随机的水平虚线。下面是一个示例:

图像到细线来自:
java - OpenCV-使用二元垫上的线进行细化会导致随机的水平虚线-LMLPHP

算法运行后的图像:
java - OpenCV-使用二元垫上的线进行细化会导致随机的水平虚线-LMLPHP

显然,图像的顶部和底部附近的虚线不应存在,因为原始图像中没有白色区域,而是以某种方式生成了这些区域。我已附上我的代码来进行以下细化,非常感谢您的帮助!

//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()从给定索引(middle)开始将3个连续像素设置为白色。 2个意外像素使您的算法“反馈”到自身中,这意味着它们触发了inARow++行。

我不是OpenCV专家,我不容易找到put()的文档,所以我不知道您应该如何向mat添加单个RGB值。但是,似乎有可能更改以下内容:

new double[]{255, 255, 255}

对此:
new double[]{255}

将导致所需的行为。

您可能也想修复“涂黑”线。

10-06 08:25