C#如何读取低质量条形码?

问题描述 投票:2回答:2

目标:

我的目标是阅读质量低劣的条形码。如果条形码的质量最高,则代码可以正常工作。

图像:

enter image description here

代码:

要裁剪条形码:

    private Point LocationXY;
    private Point LocationX1Y1;

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
            LocationXY = e.Location;
    }

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            LocationX1Y1 = e.Location;
            pictureBox1.Invalidate();
        }
    }

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            LocationX1Y1 = e.Location;

            pictureBox1.Invalidate();
            pictureBox2.Invalidate();
        }
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        Rectangle currentSelection = GetRect();
        if (currentSelection != Rectangle.Empty)
        {
            e.Graphics.DrawRectangle(Pens.Red, currentSelection);
        }
    }

    private void pictureBox2_Paint(object sender, PaintEventArgs e)
    {
        var src = GetRect();

        if (src == Rectangle.Empty) return;

        var des = new Rectangle(0, 0, src.Width, src.Height);

        e.Graphics.DrawImage(pictureBox1.Image,
            des, src, GraphicsUnit.Pixel);
    }

    private Rectangle GetRect()
    {
        return new Rectangle(
            Math.Min(LocationXY.X, LocationX1Y1.X),
            Math.Min(LocationXY.Y, LocationX1Y1.Y),
            Math.Abs(LocationXY.X - LocationX1Y1.X),
            Math.Abs(LocationXY.Y - LocationX1Y1.Y)
            );
    }


    private Bitmap GetCroppedImage()
    {
        var des = GetRect();

        if (des == Rectangle.Empty) return null;

        var b = new Bitmap(des.Width, des.Height);

        using (var g = Graphics.FromImage(b))
        {
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.DrawImage(pictureBox1.Image, new Rectangle(0, 0, des.Width, des.Height), des, GraphicsUnit.Pixel);
        }
        return b;


    }

保存图像并能够返回图像的类:

public class BarcodeImage
{
    private static Image _image;

    public static Image _Image
    {
        get
        {
            return _image;
        }
        set
        {
            _image = value;
        }
    }
}

[我在这里单击按钮以将图像保存到班级并检查条形码:

   private void checkBarcode_Click(object sender, EventArgs e)
    {
        BarcodeImage._Image = GetCroppedImage();

        ZXing.BarcodeReader reader = new ZXing.BarcodeReader();
        var result = reader.Decode((Bitmap)BarcodeImage._Image);
        if (result != null)
        {
            MessageBox.Show(result.ToString());
        }
    }

使用代码:

在这里我突出显示条形码并将其保存到picturebox2

enter image description here

下一步,单击checkBarcode_Click,它应该显示条形码值-但不显示。由于图像的质量。

我已经用高质量的条形码图像对其进行了测试,并且效果很好!

问题:

如何改善裁剪图像的质量并向我返回条形码值?

编辑:29/05/2020

我在这个社区上提出了一个新问题,以查看是否可以增加裁剪图像的大小。但这并没有任何改善:

https://stackoverflow.com/a/62068397/12485722

高质量条形码:

图像是从特定程序中取出的。

我在屏幕上打印图像,它们必须特别像这样:

enter image description here

但是它无法检测到条形码。

这是在程序上使用2倍的图像的放大版本:

enter image description here

[不幸的是,我无法使用x2放大选项,因为某些数据会在图像上移动,而无法提供准确的最终图像。最重要的是,条形码被识别!

c# barcode zxing
2个回答
3
投票

您在这里看到太多子像素数据丢失,无法用任何软件读取此条形码。

条形码使用条的相对宽度来工作-它们非常聪明地做到这一点,并且有一定的容忍空间,但数量很少。

这是您的原始条形码,放大的版本和可读的版本:

barcode examples

[如果您查看的是最右边的条与可读取的条形码,您会发现它们的大小不相等-应该是,但不是。

仅当原始图像具有足够的分辨率以正确捕获所有小节的相对尺寸时,才足够。

您需要从任何来源获得更好的数据。


0
投票

所以...如果您将获得x2缩放的图像,将其水平除以2,然后裁剪条形码,zxing将为您提供信息!因此,您所需要的-作物没有任何扭曲。因此,完成任务所需要做的所有工作-只需找到条形码的边框即可(如果您一直使用相同的格式,我认为可能是硬编码的)。如果不是,则很容易扫描图像并从右下角的黑色像素处找到它。

enter image description here

文本的代码版本:

static void Main(string[] args)
    {
        var barcodeFull = Bitmap.FromFile("barcode-x2-zoomed-dividedx2.jpg");
        var cropFromPoint = new Point(64, 578);
        var cropSize = new Size(360, 142);

        var barcode = CropAtRect((Bitmap)barcodeFull, new Rectangle(cropFromPoint, cropSize));
        ZXing.BarcodeReader reader = new ZXing.BarcodeReader();
        var result = reader.Decode(barcode);
        if (result != null)
        {
            Console.WriteLine("result : "+result.Text);
        }

        Console.ReadLine();
    }

    public static Bitmap CropAtRect(Bitmap b, Rectangle r)
    {
        Bitmap nb = new Bitmap(r.Width, r.Height);
        using (Graphics g = Graphics.FromImage(nb))
        {
            g.DrawImage(b, -r.X, -r.Y);
            return nb;
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.