2010-10-02 186 views
4

嘿,
我想从我的网络摄像头读取EAN-13条码。
我已经写了一个类来做这件事。
我正在拍摄一张来自我的摄像头的照片,修剪它只显示条形码,
并使用维基百科的代码表读取条形码。
出于某种原因,条形码被修剪,但输出总是“0-1-1-1-1-1-1-1-1-1-1-1-1”。
我不知道我是否做了任何愚蠢的错误或误解了某些东西?用网络摄像头阅读条码

我不想使用任何第三方程序!

这是我的代码现在:

public class BarcodeDecoder 
{ 
    static string[] ligerade = new string[] { "0100111", "0110011", "0011011", "0100001", "0011101", "0000101", "0010001", "0001001", "0010111" }; 
    static string[] rechtsgerade = new string[ligerade.Length]; 
    static string[] liungerade = new string[ligerade.Length]; 
    static string[] GeradeUG = new string[] { "UUUUUU", "UUGUGG", "UUGGUG", "UUGGGU", "UGUUGG", "UGGUUG", "UGGGUU", "UGUGUG", "UGUGGU", "UGGUGU" }; 
    static int[] links; 
    static int[] rechts; 
    static string result; 

    public static string Decode(Bitmap b) 
    { 
     result = ""; 
     Bitmap bb = CutOutOf(b, b.Height/2); 
     bb = trimBitmap(bb); 
     int[] lgs = GetNumberOutOf(bb); 
     int[][] rr = trimArray(lgs); 
     links = rr[0]; 
     rechts = rr[1]; 
     FillArrays(); 
     BearbeiteLinks(); 
     BearbeiteRechts(); 
     return result; 
    } 
    static void BearbeiteLinks() 
    { 
     string GU = ""; 

     string[] zahlen = new string[6]; 
     zahlen[0] = OutOfArray(links, 0, 7); 
     zahlen[1] = OutOfArray(links, 7, 7); 
     zahlen[2] = OutOfArray(links, 14, 7); 
     zahlen[3] = OutOfArray(links, 21, 7); 
     zahlen[4] = OutOfArray(links, 28, 7); 
     zahlen[5] = OutOfArray(links, 35, 7); 

     foreach (string pq in zahlen) 
     { 
      bool gerade = ligerade.ToList().IndexOf(pq) > -1; 
      if (gerade) 
      { 
       result += ligerade.ToList().IndexOf(pq).ToString(); 
       GU += "G"; 
      } 
      else 
      { 
       result += liungerade.ToList().IndexOf(pq).ToString(); 
       GU += "U"; 
      } 
     } 
     result = GeradeUG.ToList().IndexOf(GU).ToString() + result; 
    } 
    static void BearbeiteRechts() 
    { 
     string[] zahlen = new string[6]; 
     zahlen[0] = OutOfArray(rechts, 0, 7); 
     zahlen[1] = OutOfArray(rechts, 7, 7); 
     zahlen[2] = OutOfArray(rechts, 14, 7); 
     zahlen[3] = OutOfArray(rechts, 21, 7); 
     zahlen[4] = OutOfArray(rechts, 28, 7); 
     zahlen[5] = OutOfArray(rechts, 35, 7); 

     foreach (string pq in zahlen) 
     { 
      result += rechtsgerade.ToList().IndexOf(pq).ToString(); 
     } 
    } 
    static string OutOfArray(int[] ar, int startindex, int length) 
    { 
     int[] gar = new int[length]; 
     Array.Copy(ar, startindex, gar, 0, length); 
     StringBuilder bilder = new StringBuilder(); 
     for (int i = 0; i < gar.Length; i++) 
     { 
      bilder.Append(gar[i].ToString()); 
     } 
     return bilder.ToString(); 
    } 
    static Bitmap trimBitmap(Bitmap b) 
    { 
     bool alreadyBlack = false; 
     int firstblack = 0; 

     for (int i = 0; i < b.Width; i++) 
     { 
      Color gp = b.GetPixel(i, 0); 
      if ((gp.R + gp.G + gp.B)/3 < 128) 
      { 
       if (!alreadyBlack) 
       { 
        alreadyBlack = true; 
        firstblack = i; 
       } 
      } 
     } 

     bool alreadyblack = false; 
     int lastblack = 0; 
     for (int i = b.Width -1; i > 0; i--) 
     { 
      Color gpp = b.GetPixel(i, 0); 
      if ((gpp.R + gpp.G + gpp.B)/3 < 128) 
      { 
       if (!alreadyblack) 
       { 
        alreadyblack = true; 
        lastblack = i; 
       } 
      } 
     } 
     Bitmap result = new Bitmap(lastblack - firstblack, 1); 
     for (int i = firstblack; i < lastblack; i++) 
     { 
      Color c = b.GetPixel(i, 0); 
      result.SetPixel(i - firstblack, 0, c); 
     } 
     result.Save("C:\\result.bmp", System.Drawing.Imaging.ImageFormat.Bmp); 
     return result; 
    } 
    static int[][] trimArray(int[] ar) 
    { 
     int[][] res = new int[2][]; 
     int[] resl = new int[6 * 7]; 
     int[] resr = new int[6 * 7]; 
     Array.Copy(ar, 2, resl, 0, 6 * 7); 
     Array.Copy(ar, 2 + 6 * 7 + 5, resr, 0, 6 * 7); 
     res[0] = resl; 
     res[1] = resr; 
     return res; 
    } 
    static void FillArrays() 
    { 
     for (int i = 0; i < ligerade.Length; i++) 
     { 
      rechtsgerade[i] = string.Concat(ligerade[i].Reverse()); 
     } 
     for (int x = 0; x < liungerade.Length; x++) 
     { 
      liungerade[x] = Invert(rechtsgerade[x]); 
     } 
    } 
    static string Invert(string xx) 
    { 
     string xs = ""; 
     for (int y = 0; y < xx.Length; y++) 
     { 
      int fd = int.Parse(xx[y].ToString()); 
      if (fd == 0) 
       fd = 1; 
      else 
       fd = 0; 
      xs += fd.ToString(); 
     } 
     return xs; 
    } 
    static Bitmap CutOutOf(Bitmap b, int y) 
    { 
     Bitmap res = new Bitmap(b.Width, 1); 

     for (int i = 0; i < b.Width; i++) 
     { 
      Color c = b.GetPixel(i, y); 
      res.SetPixel(i, 0, c); 
     } 
     return res; 
    } 
    static int[] GetNumberOutOf(Bitmap bb) 
    { 
     List<int> intlst = new List<int>(); 
     float f = (float)bb.Width/95.0f; 
     float wd = f/2.0f; 
     for (float i = wd; i < bb.Width; i+=f) 
     { 
      Color c = bb.GetPixel((int)Math.Round(i,0), 0); 
      intlst.Add(GetOutOfColor(c)); 
     } 
     return intlst.ToArray(); 
    } 
    static int GetOutOfColor(Color c) 
    { 
     if (c.A + c.B + c.R > 128 * 3) 
     { 
      return 0; 
     } 
     return 1; 
    } 
} 

对不起代码德国名字!

+0

为什么不一次只调试一种方法?顺便说一句:trimArray应该像trimArray(int [] ar,out int [] res0,out int [] res1))并且不经常使用公共静态成员 – 2010-10-05 06:42:04

+0

一切正常,但静态int [] GetNumerOutOf(位图bb)...返回垃圾!我不知道为什么。它应该返回一个数组[95]与条形码的二进制代码 – alex 2010-10-05 15:40:38

+0

您确定您的摄像头具有足够高的分辨率以便能够提取EAN13条形码。您需要使用什么dpi /分辨率才能识别内存中的4种不同的黑条宽度和4种不同的白条宽度。如果您在阅读条码时遇到困难,请尝试提高图像质量/分辨率以查看是否可以获得正确的结果。 – 2010-10-29 07:31:17

回答

2

我看到两个问题:

1)您只扫描图像的最顶部像素行(见第二个参数GetPixel)。您的条形码可能位于图像中间,而不是顶部。

Color c = bb.GetPixel((int)Math.Round(i,0), 0); 

2)取而代之的是绿色分量的,你把alpha分量的像素着色转换成二进制值。由于alpha分量可能始终为255,因此除非有非常暗的像素,否则始终为0。

if (c.A + c.B + c.R > 128 * 3) 
+1

是它已经被剪切位图中最靠前的一行。 请参阅trimBitmap()。第二个想法根本不坏。我会试一试 – alex 2010-10-06 12:54:09