reading a barcode with a webcam - c#

Hey,
I'm trying to read a EAN-13 barcode from my webcam.
I already wrote a class to do that work.
I'm taking a picture from my webcam, trimming it to show ONLY the barcode,
and reading the barcode with the code tables from wikipedia.
For some reason, the barcode gets trimmed, but the output is always "0-1-1-1-1-1-1-1-1-1-1-1-1".
I wonder if i did any stupid mistake or misunderstood something?
I do not want to use ANY third-party programs!
this is my code for now:
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;
}
}
Sorry for german names in the code!

I see two problems:
1) You only scan the top most pixel row of your image (see the second parameter of GetPixel). Your barcode is probably in the middle of the image and not at the top.
Color c = bb.GetPixel((int)Math.Round(i,0), 0);
2) Instead of the green component, you take the alpha component to convert the colored pixel into a binary value. Since the alpha component is probably always 255, you always get 0 unless you have a very dark pixel.
if (c.A + c.B + c.R > 128 * 3)

Related

Two GC420t printers different ZPL Outcome (ZPL, C#)

i have 2 Zebra GC420t printers and a wpf application creating and sending ZPL code to selected printers.
The printed labels are too way different. See the image below.
The outcomes and printer configurations
Pinted ZPL code is: (label is 10x8.1 cm)
^XA
^PON
^CI27
^MMT
^PW800
^LL648
^FX Pictogram0
^FO632,104
^GFA,1300,1300,13,,W0G1GCM0W0G3G4M0,::::::::::::::::::::::::S0G7GCQ0P0HFG1HFGEP0K0G4H0G3IFGBJFG8G0G3L0K0G7G0G7JFGBG8G1IFGCG7L0K0G3JFG0G1GFG8H0IFGEL0K0G3HFGCH0G1GFG8I0G3GFGEL0K0G3GFJ0G7GBHFG8I0GEL0K0G3G8G0G3IFG9KFG0GEL0K0G3LFG0G7KFGEL0K0G3KFG8H0G7JFGEL0K0G1IFGEK0G1IFGCL0K0G1HFG8N0G7GFGCL0K0G1GEQ0G1GEG0G3G8I0K0G3GCO0G6G0G1GEH7G8I0K0G3GCO0H7G1GEH7J0K0G3GCO0G7GFG1GEG7G6J0K0G3GCO0G3GEG1GEGFG6J0K0G3GCO0G3GFG8GCGFGEJ0K0G1G8O0G3GFG9GCGDGEJ0I0G2G0G3G8G1G8M0G3GFG9GEGFG8J0I0G7G0G3G9GBGCN0GFG9HFG8J0I0G7GBG3G9GFG8N0GFGDHFG8J0I0G3GFG7GDGFO0GFGDGFGBK0I0G3GFG7GDGFO0G7G9GEG2K0I0G3GEG7HFO0G3G1GCL0I0G3JFN0G3GFG8G3L0I0G1GFGBGFGEN0G3IFGCK0J0GFG8G3GCN0KFG8J0J0GFG8GFGCM0G7LFG8I0J0G7GCGFG8M0G7JFG3GFG8I0G3JFGCG7JFI0G1HFGEG7H0G1G8I0G3JFG8G1JFI0G3HFGEG7G8L0G3PFI0G7HFGEG3GFL0G3PFI0G7HFGEG1GFL0G3PFI0G3HFGEG0GFL0G3PFI0G1HFGEN0G3PFJ0G7HFG8H0G3G8I0G3PFJ0G7HFGCG0G1GFG8I0G3PFJ0G1HFG8G1HFG8I0V0KFGCJ0V0G7IFGEK0X0G7G8L0,:::::::::::::::::::::::::::::
^FS
^FX Pictogram1
^FO632,280
^GFA,1300,1300,13,,:::::::::::::::Q0GFGES0P0G7HFGCR0P0IFGER0O0G3JFG8Q0O0G7JFGCQ0::O0KFGEQ0:O0G7JFGCQ0:::::O0G3JFG8Q0::::::O0G1JFR0::::::P0IFGER0:::::P0G7HFGCR0::::::P0G3HFG8R0::P0G1HFS0Q0GFGES0Q0G3G8S0,::Q0G7GCS0P0G1HFS0P0G3HFG8R0P0G7HFGCR0P0IFGER0:O0G1JFR0::::::P0IFGER0P0G7HFGCR0:P0G1HFS0Q0GFGES0,::::::::::::::
^FS
^FX Pictogram2
^FO632,456
^FS
^FX ItemNumber
^CF0,30
^FO25,27,0
^FB608,1,,L,
^FH
^FD
10001A
^FS
^FX ItemName
^CF0,50
^FO25,55,0
^FB608,1,,L,
^FH
^FD
_52_55_43_4F_47_45_4E_20_44_46_4C_20_33_30_30
^FS
^FX BatchNumber
^CF0,50
^FO25,105,0
^FB608,1,,L,
^FH
^FD
17-0001
^FS
^FX Amount
^CF0,30
^FO25,150,0
^FB608,1,,L,
^FH
^FD
120 Kg
^FS
^FX LabelDate
^CF0,30
^FO25,185,0
^FB608,1,,L,
^FH
^FD
29.05.2017
^FS
^FX Barcode
^FO25,230,0
^BY3,2,75
^BCN
^FD
869316388539
^FS
^FX Warnings
^CF0,20
^FO25,350,0
^FB560,30,,,L,
^FH
^FD
_48_33_30_32_3A_20_59_75_74_75_6C_6D_61_73_69_20_68_61_6C_69_6E_64_65_20_7A_61_72_61_72_6C_69_64_69_72_2E_5C_26_48_33_31_38_3A_20_43_69_64_64_69_20_67_F6_7A_20_68_61_73_61_72_69_6E_61_20_79_6F_6C_20_61_E7_61_72_2E_5C_26_50_32_36_34_3A_20_45_6C_6C_65_E7_6C_65_6D_65_64_65_6E_20_73_6F_6E_72_61_20_85_20_69_6C_65_20_69_79_69_63_65_20_79_69_6B_61_79_69_6E_2E_5C_26_50_32_38_30_3A_20_4B_6F_72_75_79_75_63_75_20_65_6C_64_69_76_65_6E_2F_6B_6F_72_75_79_75_63_75_20_6B_69_79_61_66_65_74_2F_67_F6_7A_20_6B_6F_72_75_79_75_63_75_2F_79_FC_7A_20_6B_6F_72_75_79_75_63_75_20_6B_75_6C_6C_61_6E_69_6E_2E_A0_5C_26_50_33_31_30_3A_20_48_65_6D_65_6E_A0_55_4C_55_53_41_4C_20_5A_45_48_49_52_20_44_41_4E_49_53_4D_41_20_4D_45_52_4B_45_5A_49_4E_49_4E_20_31_31_34_20_4E_4F_4C_55_20_54_45_4C_45_46_4F_4E_55_4E_55_A0_76_65_79_61_20_64_6F_6B_74_6F_72_75_2F_68_65_6B_69_6D_69_20_61_72_61_79_69_6E_2E_A0_5C_26_50_33_30_31_2B_50_33_31_32_3A_20_59_55_54_55_4C_44_55_47_55_4E_44_41_3A_20_4B_65_6E_64_69_6E_69_7A_69_20_69_79_69_20_68_69_73_73_65_74_6D_69_79_6F_72_73_61_6E_69_7A_A0_55_4C_55_53_41_4C_20_5A_45_48_49_52_20_44_41_4E_49_53_4D_41_20_4D_45_52_4B_45_5A_49_4E_49_4E_20_31_31_34_20_4E_4F_4C_55_20_54_45_4C_45_46_4F_4E_55_4E_55_A0_76_65_79_61_20_64_6F_6B_74_6F_72_75_2F_68_65_6B_69_6D_69_20_61_72_61_79_69_6E_2E_5C_26_50_33_30_35_2B_50_33_35_31_2B_50_33_33_38_3A_20_47_D6_5A_20_49_4C_45_20_54_45_4D_41_53_49_20_48_41_4C_49_4E_44_45_3A_20_53_75_20_69_6C_65_20_62_69_72_6B_61_E7_20_64_61_6B_69_6B_61_20_64_69_6B_6B_61_74_6C_69_63_65_20_64_75_72_75_6C_61_79_69_6E_2E_20_54_61_6B_69_6C_69_20_76_65_20_79_61_70_6D_61_73_69_20_6B_6F_6C_61_79_73_61_2C_20_6B_6F_6E_74_61_6B_20_6C_65_6E_73_6C_65_72_69_20_E7_69_6B_61_72_74_69_6E_2E_20_44_75_72_75_6C_61_6D_61_79_61_20_64_65_76_61_6D_20_65_64_69_6E_2E_5C_26_50_35_30_31_3A_20_49_E7_65_72_69_67_69_2F_6B_61_62_69_20_85_20_62_65_72_74_61_72_61_66_20_65_64_69_6E_2E
^FS
^FX FormNumber
^CF0,30
^FO600,630,0
^FB160,1,,C,
^FH
^FDF 540.006.2^FS
^XZ
You can chech zpl code in labelary.com/viewer.html
I am using RawPrinterHelper to send ZPL string to printer.
Can anyone help me please ?
To any poor soul like me that strangling to print an image using ZPL language, here what i have done.
int x = 300, y = 300;
pictogram0 = ZplImageConverter.GetZpl(ZplTools.ResizeImageData(ZplTools.RotateImageData(pictogramList[0]), x, y));
public class ZplImageConverter
{
public const int MaxBlacklimit = 765;
private static Dictionary<int, String> CompressMap
{
get
{
if (_CompressMap == null)
{
_CompressMap = new Dictionary<int, string>();
_CompressMap.Add(1, "G");
_CompressMap.Add(2, "H");
_CompressMap.Add(3, "I");
_CompressMap.Add(4, "J");
_CompressMap.Add(5, "K");
_CompressMap.Add(6, "L");
_CompressMap.Add(7, "M");
_CompressMap.Add(8, "N");
_CompressMap.Add(9, "O");
_CompressMap.Add(10, "P");
_CompressMap.Add(11, "Q");
_CompressMap.Add(12, "R");
_CompressMap.Add(13, "S");
_CompressMap.Add(14, "T");
_CompressMap.Add(15, "U");
_CompressMap.Add(16, "V");
_CompressMap.Add(17, "W");
_CompressMap.Add(18, "X");
_CompressMap.Add(19, "Y");
_CompressMap.Add(20, "g");
_CompressMap.Add(40, "h");
_CompressMap.Add(60, "i");
_CompressMap.Add(80, "j");
_CompressMap.Add(100, "k");
_CompressMap.Add(120, "l");
_CompressMap.Add(140, "m");
_CompressMap.Add(160, "n");
_CompressMap.Add(180, "o");
_CompressMap.Add(200, "p");
_CompressMap.Add(220, "q");
_CompressMap.Add(240, "r");
_CompressMap.Add(260, "s");
_CompressMap.Add(280, "t");
_CompressMap.Add(300, "u");
_CompressMap.Add(320, "v");
_CompressMap.Add(340, "w");
_CompressMap.Add(360, "x");
_CompressMap.Add(380, "y");
_CompressMap.Add(400, "z");
}
return _CompressMap;
}
}
private static Dictionary<int, String> _CompressMap;
public static string GetZpl(byte[] imageData, bool useCompression = true)
{
var imgConverter = new ImageConverter();
var bmp = (Bitmap)imgConverter.ConvertFrom(imageData);
var bytesPerRow = bmp.Width / 8;
if (bmp.Width % 8 > 0)
bytesPerRow = (((int)(bmp.Width / 8)) + 1);
else
bytesPerRow = bmp.Width / 8;
var totalBytes = bytesPerRow * bmp.Height;
string hex = CreateMonochromeHex(bmp, bytesPerRow, totalBytes);
return string.Format("^GFA,{0},{0},{1},{2}", totalBytes, bytesPerRow, useCompression ? EncodeHexAscii(hex, bytesPerRow) : hex);
}
#region Helpers
private static string CreateMonochromeHex(Bitmap bmp, int bytesPerRow, int totalBytes)
{
var sb = new StringBuilder();
var graphics = Graphics.FromImage(bmp);
graphics.DrawImage(bmp, 0, 0);
var auxBinaryChar = new char[] { '0', '0', '0', '0', '0', '0', '0', '0' };
int index = 0;
for (int h = 0; h < bmp.Height; h++)
{
for (int w = 0; w < bmp.Width; w++)
{
//Remove borders
if (h == 0 || w == bmp.Width - 1 || w == 0 || h == bmp.Height - 1)
{
auxBinaryChar[index] = '0';
index++;
}
else
{
var rgb = bmp.GetPixel(w, h);
char auxChar = '1';
/* Determine using Luma
* Source1 = http://web.archive.org/web/20141017085834/http://nicholas.piasecki.name:80/blog/2013/02/using-the-epl2-gw-command/
* Source2 = http://web.archive.org/web/20141025194839/https://en.wikipedia.org/wiki/Luma_(video)
*
* var threshold = 127;
* var color = bitmap.GetPixelx, y;
* var luminance = color.R * 0.3 + color.G * 0.59 + color.B * 0.11;
* dotsindex = luminance < threshold;
*
*/
//If color is not pure white then apply thermal heat to draw black otherwise do not apply thermal heat to draw nothing (white)
if ((rgb.R + rgb.G + rgb.B) >= ZplImageConverter.MaxBlacklimit)
auxChar = '0';
auxBinaryChar[index] = auxChar;
index++;
}
if (index == 8 || w == (bmp.Width - 1))
{
sb.Append(FourByteBinary(new String(auxBinaryChar)));
auxBinaryChar = new char[] { '0', '0', '0', '0', '0', '0', '0', '0' };
index = 0;
}
}
sb.Append("\n");
}
return sb.ToString();
}
private static string FourByteBinary(string binaryStr)
{
return string.Format("{0:X2}", Convert.ToByte(binaryStr, 2));
}
private static string EncodeHexAscii(string hex, int bytesPerRow)
{
int maxlinea = bytesPerRow * 2;
var sbCode = new StringBuilder();
var sbLinea = new StringBuilder();
String previousLine = null;
int counter = 1;
char aux = hex[0];
bool firstChar = false;
for (int i = 1; i < hex.Length; i++)
{
if (firstChar)
{
aux = hex[i];
firstChar = false;
continue;
}
if (hex[i] == '\n')
{
if (counter >= maxlinea && aux == '0')
{
sbLinea.Append(",");
}
else if (counter >= maxlinea && aux == 'F')
{
sbLinea.Append("!");
}
else if (counter > 20)
{
int multi20 = (counter / 20) * 20;
int resto20 = (counter % 20);
sbLinea.Append(CompressMap[multi20]);
if (resto20 != 0)
{
sbLinea.Append(CompressMap[resto20] + aux);
}
else
{
sbLinea.Append(aux);
}
}
else
{
sbLinea.Append(CompressMap[counter] + aux);
}
counter = 1;
firstChar = true;
if (sbLinea.ToString().Equals(previousLine))
{
sbCode.Append(":");
}
else
{
sbCode.Append(sbLinea.ToString());
}
previousLine = sbLinea.ToString();
sbLinea.Length = 0;
continue;
}
if (aux == hex[i])
{
counter++;
}
else
{
if (counter > 20)
{
int multi20 = (counter / 20) * 20;
int resto20 = (counter % 20);
sbLinea.Append(CompressMap[multi20]);
if (resto20 != 0)
{
sbLinea.Append(CompressMap[resto20] + aux);
}
else
{
sbLinea.Append(aux);
}
}
else
{
sbLinea.Append(CompressMap[counter] + aux);
}
counter = 1;
aux = hex[i];
}
}
return sbCode.ToString();
}
#endregion
}
public static class ZplTools
{
public static string Normalize(string input)
{
if (string.IsNullOrEmpty(input))
return null;
var sb = new StringBuilder();
for (int i = 0; i < input.Length; i++)
{
var byteArray = Encoding.GetEncoding(1252).GetBytes(input.Substring(i, 1));
var hexString = BitConverter.ToString(byteArray);
sb.Append("_" + hexString.Replace("-", "_"));
}
return sb.ToString();
}
public static byte[] ConvertToMonochromeBitmap(byte[] imageData)
{
var converter = new System.Drawing.ImageConverter();
var image = (System.Drawing.Bitmap)converter.ConvertFrom(imageData);
return (byte[])converter.ConvertTo(image.ConvertToMonochromeTiff(), typeof(byte[]));
}
public static byte[] ResizeImageData(byte[] imageData, int with, int height)
{
var converter = new System.Drawing.ImageConverter();
using (var source = (System.Drawing.Image)converter.ConvertFrom(imageData))
{
using (var thumbnail = new System.Drawing.Bitmap(with, height))
{
using (var g = System.Drawing.Graphics.FromImage(thumbnail))
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(source, 0, 0, with, height);
}
return (byte[])converter.ConvertTo(thumbnail, typeof(byte[]));
}
}
}
public static byte[] RotateImageData(byte[] imageData)
{
System.Drawing.ImageConverter converter = new System.Drawing.ImageConverter();
using (var image = (System.Drawing.Image)converter.ConvertFrom(imageData))
{
image.RotateFlip(System.Drawing.RotateFlipType.Rotate90FlipXY);
return (byte[])converter.ConvertTo(image, typeof(byte[]));
}
}
public static string GetImageZplUploadString(byte[] imageData, string imageName)
{
return string.Format("^XA~DYE:{2},P,P,{0},,{1}^XZ", imageData.Length, ZplTools.GetASCIHexString(imageData), imageName);
}
public static string GetASCIHexString(byte[] data)
{
StringBuilder hex = new StringBuilder();
foreach (byte b in data)
hex.AppendFormat("{0:X2}", b);
return hex.ToString();
}
}
I don't know why but adding a ^FWN command to the top of the ZPL solved the problem.

Write 3 arrays to 1

I have 3 arrays: x, y and z. How can I write all three to one in one-after-one mode?
For example: I have X=1,2 Y=3,4 Z=5,6
I need an array W = X[1],Y[1],Z[1],X[2],Y[2],Z[2] ... X[n],Y[n],Z[n]
float[] posX = new float[rmv2.lod[0].VerticesCount[0]];
float[] posY = new float[rmv2.lod[0].VerticesCount[0]];
float[] posZ = new float[rmv2.lod[0].VerticesCount[0]];
for (int i = 0; i < 1; i += 3)
{
posX[i] = rmv2.lod[0].Mesh[0].Vertex[i].X;
posY[i + 1] = rmv2.lod[0].Mesh[0].Vertex[i].Y;
posZ[i + 2] = rmv2.lod[0].Mesh[0].Vertex[i].Z;
}
I don't see the w array you're trying to write the output to. Are you looking for something like this?
int n = rmv2.lod[0].VerticesCount[0];
float[] posX = new float[n];
float[] posY = new float[n];
float[] posZ = new float[n];
float[] w = new float[n * 3];
for (int i = 0; i < n; i++)
{
posX[i] = rmv2.lod[0].Mesh[0].Vertex[i].X;
posY[i] = rmv2.lod[0].Mesh[0].Vertex[i].Y;
posZ[i] = rmv2.lod[0].Mesh[0].Vertex[i].Z;
w[i * 3 + 0] = rmv2.lod[0].Mesh[0].Vertex[i].X;
w[i * 3 + 1] = rmv2.lod[0].Mesh[0].Vertex[i].Y;
w[i * 3 + 2] = rmv2.lod[0].Mesh[0].Vertex[i].Z;
}
Perhaps you should look at jagged arrays...
https://msdn.microsoft.com/en-us/library/2s05feca.aspx
Try this:
float[] x = new float[] { 1, 2, 9 };
float[] y = new float[] { 3, 4 };
float[] z = new float[] { 5, 6 };
int max = Math.Max(x.Length, Math.Max(y.Length, z.Length));
List<float> combined = new List<float>();
for (int i = 0; i < max; i++)
{
if (x.Length > i) combined.Add(x[i]);
if (y.Length > i) combined.Add(y[i]);
if (z.Length > i) combined.Add(z[i]);
}
Produces a list with the combined arrays, regardless of their original lengths.
1, 3, 5, 2, 4, 6, 9
If I right understand you, try this solution. With this method arrays can have different length
static T[] ConcatOneAfterOne<T>(params T[][] arrays)
{
int outputArrayLength = 0;
for (int i = 0; i < arrays.Length; i++)
{
outputArrayLength += arrays[i].Length;
}
T[] output = new T[outputArrayLength];
int outputIndex = 0;
int sourceIndex = 0;
while (outputIndex != outputArrayLength)
{
for (int arrayIndex = 0; arrayIndex < arrays.Length; arrayIndex++)
{
if (sourceIndex < arrays[arrayIndex].Length)
{
output[outputIndex++] = arrays[arrayIndex][sourceIndex];
}
}
sourceIndex++;
}
return output;
}
[Test]
static void ConcatOneAfterOneTest()
{
int[] result = ConcatOneAfterOne(new[] { 1, 2 }, new[] { 3, 4 }, new[] { 5, 6 });
CollectionAssert.AreEqual(new int[] { 1, 3, 5, 2, 4, 6 }, result);
}

Neural Net - Feed Forward, Matrix Multiplication in C#

I'm attempting to make a Neural Network in C#, I based the design in a python code I made a while back. But somehow the end result is not the same.
I'm new to C# and I'm using it in Unity, so I have limitation to library uses.
In python numpy can do matrix multiplications with the numpy.dot() method. I Haven't found something similar in C#, especially in Unity. So I had to do it by hand.
The Python code:
import numpy as np
class NN:
def __init__(self, n_input, n_hidden_layers, n_hidden_nodes, n_output):
self.weights_hidden = []
for n in range(n_hidden_layers + 1):
if n == 0:
size = n_input, n_hidden_nodes
elif n == n_hidden_layers:
size = n_hidden_nodes, n_output
else:
size = n_hidden_nodes, n_hidden_nodes
self.weights_hidden.append(
np.random.random(size)
)
#staticmethod
def activation(x):
return np.tanh(x)
def feed_forward(self, ip):
input_values = (ip - np.mean(ip, axis=0)) / np.std(ip, axis=0)
for w, weights in enumerate(self.weights_hidden):
if w == 0:
result = input_values
result = np.array(
map(self.activation, result.dot(weights))
)
return result
ANN = NN(n_input=5, n_hidden_layers=2, n_hidden_nodes=3, n_output=1)
print ANN.feed_forward([1, 2, 3, 4, 5])
My attempt to convert it to C#.
using UnityEngine;
using System.Collections;
public class neural_net : MonoBehaviour {
int n_inputs;
int n_hidden_layers;
int n_hidden_nodes;
int n_outputs;
float[] inputs;
ArrayList hidden_weights;
ArrayList hidden_results;
float[] output_results;
public void init(int n_inputs, int n_hidden_layers, int n_hidden_nodes, int n_outputs){
this.n_inputs = n_inputs;
this.n_hidden_layers = n_hidden_layers;
this.n_hidden_nodes = n_hidden_nodes;
this.n_outputs = n_outputs;
this.hidden_weights = new ArrayList ();
this.hidden_results = new ArrayList ();
this.output_results = new float[n_outputs];
int rows;
int columns;
for (int h = 0; h < n_hidden_layers + 2; h++) {
if (h == 0){
// input -> hidden
rows = n_inputs;
columns = n_hidden_nodes;
}
else if(h == n_hidden_layers + 1){
// hidden -> output
rows = n_hidden_nodes;
columns = n_outputs;
}
else {
// hidden -> hidden
rows = n_hidden_nodes;
columns = n_hidden_nodes;
}
float[] hidden_result = new float[rows*columns];
hidden_results.Add(hidden_results);
float[,] target = new float[rows,columns];
string test = "";
for(int r = 0; r < rows; r++){
for(int c = 0; c < columns; c++){
target[r,c] = Random.Range(0.0f, 1.0f);
test += target[r,c] + ", ";
}
}
hidden_weights.Add(target);
}
}
float activation(float x){
// tanh(x);
return (1 - Mathf.Exp (-2 * x)) / (1 + Mathf.Exp (-2 * x));
}
float[] _dot_matrix(float[] results, float[,] weights){
float[] new_matrix = new float[weights.GetLength(1)];
string t0 = "";
for (int r = 0; r < weights.GetLength(1); r++){
float res = 0;
for (int c = 0; c < weights.GetLength(0); c++) {
res += results[c] * weights[c,r];
}
new_matrix[r] = res;
}
return new_matrix;
}
float[] _map_activation(float[] pre_results){
float[] results = new float[pre_results.Length];
for (int i = 0; i < results.Length; i++) {
results[i] = activation(pre_results[i]);
}
return results;
}
float[] feed_forward(){
int h;
for (h = 0; h < n_hidden_layers + 2; h++) {
float[] dot_matrix_result;
if(h == 0){
dot_matrix_result = _dot_matrix(inputs, (float[,])hidden_weights[h]);
}
else if (h == n_hidden_layers +1){
dot_matrix_result = _dot_matrix((float[])hidden_results[h-1], (float[,])hidden_weights[h]);
output_results = _map_activation(dot_matrix_result);
break;
}
else {
dot_matrix_result = _dot_matrix((float[])hidden_results[h-1], (float[,])hidden_weights[h]);
}
float[] result = _map_activation(dot_matrix_result);
hidden_results[h] = _map_activation(result);
}
return output_results;
}
float[] normalize_input(float[] inputs){
float sum = 0.0f;
for (int i = 0; i < inputs.Length; i++) {
sum += inputs[i] ;
}
float average = sum / inputs.Length;
float[] deviations = new float[inputs.Length];
for (int i = 0; i < inputs.Length; i++) {
deviations[i] = Mathf.Pow(inputs[i] - average,2);
}
float sum_deviation = 0;
for (int i = 0; i < deviations.Length; i++) {
sum_deviation += deviations[i];
}
float variance = sum_deviation / deviations.Length;
float std = Mathf.Sqrt (variance);
for (int i = 0; i < inputs.Length; i++) {
inputs[i] = (inputs[i] - average)/std;
}
return inputs;
}
public void start_net(float[] inputs){
this.inputs = normalize_input(inputs);
feed_forward ();
}
}
I run the net from other script using the init method and then the start_net() method.
I made a test with not random weights and fixed input data, but it didn't came to the same result as the python code.
What's wrong with the C# code?

How do I calculate LINEST in C# with a zero intercept?

The normal Linest is easy, but I don't know how to "b is set equal to 0 and the m-values are adjusted to fit y = mx."
static class Program
{
static void Main(string[] args)
{
var yValues = new double[] { 1, 9, 5, 7 };
var xValues = new double[] { 0, 4, 2, 3 };
var noConst = Linest(yValues, xValues);
Console.WriteLine("m = {0}, b = {1}", noConst.Slope, noConst.Intercept);
}
public static LineSpec Linest(IList<double> yValues, IList<double> xValues)
{
var yAvg = yValues.Sum() / yValues.Count;
var xAvg = xValues.Sum() / xValues.Count;
double upperSum = 0;
double lowerSum = 0;
for (var i = 0; i < yValues.Count; i++)
{
upperSum += (xValues[i] - xAvg) * (yValues[i] - yAvg);
lowerSum += (xValues[i] - xAvg) * (xValues[i] - xAvg);
}
var m = upperSum / lowerSum;
var b = yAvg - m * xAvg;
return new LineSpec() { Slope = m, Intercept = b };
}
}
struct LineSpec
{
public double Slope { get; set; }
public double Intercept { get; set; }
}
This is a math question, not a coding question. Use linear regression without the intercept term.
public static LineSpec LinestConst(IList<double> yValues, IList<double> xValues)
{
var yAvg = yValues.Sum() / yValues.Count;
var xAvg = xValues.Sum() / xValues.Count;
double upperSum = 0;
double lowerSum = 0;
for (var i = 0; i < yValues.Count; i++)
{
upperSum += (xValues[i] * yValues[i] );
lowerSum += (xValues[i] * xValues[i] );
}
var m = upperSum / lowerSum;
var b = 0;
return new LineSpec() { Slope = m, Intercept = b };
}

records on Access database are all the same in my code

I have written the following code to generate some security codes but these codes doesnt save correctly in access and all records are the same.although I traced my code and each time a different code is genrated but these diffrent codes doesnt save in access.just first code saves corectly and other records saves like first record
OleDbCommand cmd = new OleDbCommand();
cmd.CommandType = CommandType.Text;
cmd.Connection = myconn;
label7.Text = "";
int[] s = new int[15];
int[] a = { 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
int[] b = { 0, 0, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
int[] result1 = new int[13];
int[] result2 = new int[13];
int f = Convert.ToInt32(textBox1.Text);
int m = Convert.ToInt32(textBox2.Text);
double sum1 = 0;
double div1 = 0;
double sum2 = 0;
double div2 = 0;
int z = Convert.ToInt32(textBox2.Text) - Convert.ToInt32(textBox1.Text);
if (z >= 400)
{
Form1 h = new Form1();
h.Close();
}
while (f <= m)
{
int l = f;
for (int i = 0; i <= 3; i++)
{
s[i] = 2;
}
s[4] = 0;
s[5] = 1;
for (int i = 12; i >= 6; i--)
{
s[i] = l % 10;
l = l / 10;
}
for (int i = 0; i <= 12; i++)
{
result1[i] = s[i] * a[i];
result2[i] = s[i] * b[i];
sum1 += result1[i];
sum2 += result2[i];
}
div1 = sum1 / 11;
div2 = sum2 / 11;
double value1 = div1;
int r = (int)((value1 - (int)value1) * 10);
double value2 = div2;
int o = (int)((value2 - (int)value2) * 10);
if (r == 9)
{
s[13] = 0;
}
else
{
s[13] = r + 1;
}
if (o == 9)
{
s[14] = 0;
}
else
{
s[14] = o + 1;
}
string we = "";
for (int q = 0; q <= 14; q++)
{
we += s[q];
}
cmd.Parameters.AddWithValue("#SP", we);
cmd.CommandText = "INSERT INTO [Counter](SubscriptionCode)" + " VALUES (#SP)";
myconn.Open();
cmd.ExecuteNonQuery();
myconn.Close();
f++;
label7.Text += " \n ";
}
Check if the command is updated with the correct value on each iteration

Categories