ZXing:寻找条形码的边界矩形

6
我正在研究ResultPoints,该函数返回与图像中的条形码相关的点。
对于QR码,ResultPoints返回一组4个点,它们是QR码每个角的四个方框的坐标。当我使用一个Barcode进行相同的实验时,它返回两个点,这两个点表示条形码的宽度。我如何找到该条形码的边界矩形呢?是否有办法可以使用ResultPoints数组计算条形码左上角和右下角的坐标呢?
经过一番研究,我发现了WhiteRectangleDetector类。这正是我感兴趣的东西,但当我开始尝试时,它给出了部分结果而不是确切的结果。我附上了使用WhiteRectangleDetector得到的结果图像,但正如我们所看到的,它只填充了条形码的中间部分,而不是整个矩形部分。所以我想知道是否能够将整个矩形部分涂色。
我的代码:
        barcodeBitmap = (Bitmap)Bitmap.FromFile("barcode-image.png");
        var luminanceSource = new ZXing.BitmapLuminanceSource(barcodeBitmap);
        var binarizer = new ZXing.Common.HybridBinarizer(luminanceSource);
        var bitMatrix = binarizer.BlackMatrix;

        var whiterect = WhiteRectangleDetector.Create(bitMatrix);

        ResultPoint[] whiterectpts = whiterect.detect();
        if (whiterectpts != null)
        {
            Console.WriteLine("\nWhiteRectangleDetector\n");
            foreach (var w in whiterectpts)
            {
                Console.WriteLine(w);
            }
            Rectangle whiterectangle = new Rectangle((int)whiterectpts[0].X, (int)whiterectpts[0].Y, (int)(whiterectpts[2].X - whiterectpts[1].X), (int)(whiterectpts[1].Y - whiterectpts[0].Y));
            img = Image.FromFile("barcode-image.png");
            g = Graphics.FromImage(img);
            g.DrawRectangle(pen, whiterectangle);
            img.Save("crop2.png");
        }

裁剪后的图片


嗨,Mancoolgunnda.. 你得到了条形码的边界矩形吗? - Sathish Kumar
3个回答

4
通过ResultPoints你可以得到条形码的边缘坐标。通过WhiteRectangleDetector(WRDet)你可以得到条形码顶部的y坐标和高度。将所有这些信息放在一起,就可以得到精确的坐标!
具体分解如下:
- 左上角:从WRDet中获取的顶部y值,通过最左侧的ResultPoint获取的x值。 - 右上角:从WRDet中获取的顶部y值,通过最右侧的ResultPoint获取的x值。 - 左下角:从WRDet中获取的顶部y值加上WRDet的高度,通过最左侧的ResultPoint获取的x值。 - 右下角:从WRDet中获取的顶部y值加上WRDet的高度,通过最右侧的ResultPoint获取的x值。
看起来调用ResultPoints和WRDet可能会有些繁琐,但是如果初始搜索中心位于条形码内部,WRDet算法非常快速。可以使用以下构造函数修改初始搜索中心。
public WhiteRectangleDetector(BitMatrix image, int initSize, int x, int y)

您需要确保 x 值在左右 ResultPoint 之间,而对于 y 值,则可以选择一个 ResultPoint 的 y 值。


顺便提一下,为什么 WhiteRectangleDetector 只捕获了水平部分。这是因为有一个初始矩形沿着其四个边扩展,直到没有更多的黑点落在上面。顶部和底部是正确的,而在 1D 条形码中,白色条形阻止了算法进一步搜索。

WhiteRectangleDetector 对于 2D 码(没有垂直的白色条形覆盖整个码的高度)的效果更好,当然前提是您知道初始搜索中心的位置。


0

关于QR码:在研究ZXING的源代码后,我找到了一个简单的解决方案。每个QR码的resultsPoints按以下顺序包含以下点:

索引0:bottomLeft 索引1:topLeft 索引2:topRight

因此,您可以例如创建自己的类,将resultPoints作为构造函数参数,以创建在图像中保存QR码坐标的对象。以下代码是用C#编写的,因为我们使用Xamarin,但Java代码看起来类似:

public class QRCodeCoordinates
{
    public float X1 { get; set; }
    public float X2 { get; set; }
    public float Y1 { get; set; }
    public float Y2 { get; set; }

    public QRCodeCoordinates(ZXing.ResultPoint[] resultPoints)
    {
        this.X1 = resultPoints[0].X; // index 0: bottom left
        this.X2 = resultPoints[2].X; // index 2: top right
        this.Y1 = resultPoints[2].Y; // index 2: top right
        this.Y2 = resultPoints[0].Y; // index 0: bottom left            
    }
}

1
为什么要使用浮点数?单位是什么?为什么不只用像素?如何获取像素数量?为什么我在整个互联网上都找不到这个信息? - Roel

0

我正在研究这个问题,也许你可以在不同的构造函数中修改以下参数来解决你的问题:在WhiteRectangleDetector.java中以下构造函数中的initSize参数扩大了初始搜索区域,可能会导致检测到整个1D条形码。

public WhiteRectangleDetector(BitMatrix image, int initSize, int x, int y) throws NotFoundException {...}

我想问一下:WhiteRectangleDetector适用于1D和/或QR码吗?你试过MonochromeRectangleDetector吗?


看起来,WhiteRectangleDetector和MonochromeRectangleDetector(但我找不到后者的任何文档)都旨在检测1D条形码中的白色/黑色“条纹”。 (出于好奇心,我仍然在各种带有QR码的图像上测试了两者,但它们无法检测到它们。) - ᴠɪɴᴄᴇɴᴛ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接