2010-10-02 98 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