/// <summary> /// build template List from a Gray image /// </summary> /// <param name="image">input image</param> /// <param name="buildXMLTemplateFile">true to build a xml file with current templates</param> /// <param name="angles">the number of angles, default to 360</param> /// <param name="sizes">number of sizes, default to 1</param> /// <param name="minRatio">The ratio of smallest size to original, default to 0.6</param> /// <param name="maxFeaturesPerLevel">the array of maximum features per pyrimid level, default to 200 in DEFAULT_MAX_FEATURES_PER_LEVEL from ImageTemplatePyramid.cs:56, /// increase to increase the precision in expense of detection time-delay</param> /// <param name="userFunc">Input User Function for customization and diversity</param> /// <returns>List of templates.</returns> public static List <TemplatePyramid> buildTemplate(Gray <byte>[,] image, int Width, int Height, bool buildXMLTemplateFile = false, int angles = 360, int sizes = 1, float minRatio = 0.6f, int[] maxFeaturesPerLevel = null, Func <TemplatePyramid, Gray <byte> [, ], TemplatePyramid> userFunc = null) { List <TemplatePyramid> retList = new List <TemplatePyramid>(); float Ratio = 1; Gray <byte>[,] tempIMG; rotateLoad(retList, image, angles, Width, Height, false, userFunc: validateFeatures); for (int i = 0; i < sizes - 1; i++) { Ratio -= (float)(1 - minRatio) / sizes; int width = (int)(image.Width() * Ratio); int height = (int)(image.Height() * Ratio); DotImaging.Primitives2D.Size Nsize = new DotImaging.Primitives2D.Size(width, height); tempIMG = ResizeExtensions_Gray.Resize(image, Nsize, Accord.Extensions.Imaging.InterpolationMode.NearestNeighbor); rotateLoad(retList, tempIMG, angles, Width, Height, false, maxFeaturesPerLevel, image.ToString(), userFunc: userFunc); } if (buildXMLTemplateFile) { XMLTemplateSerializer <ImageTemplatePyramid <ImageTemplate>, ImageTemplate> .ToFile(retList, Path.Combine(Directory.GetParent(Directory.GetCurrentDirectory()).FullName, "Resources", "template" + ".xml")); } return(retList); }
/// <summary> /// build template List from a XML file /// </summary> /// <param name="filename">input XML file name, the file has to be in the current directory </param> /// <param name="buildXMLTemplateFile">true to build a xml file with current templates</param> /// <param name="angles">the number of angles, default to 360</param> /// <param name="sizes">number of sizes, default to 1</param> /// <param name="CropToSqr">decides whether to crop the image to sqrside to prevent edges issues</param> /// <param name="maxFeaturesPerLevel">the array of maximum features per pyrimid level, default (null) would evaluate to 200 in DEFAULT_MAX_FEATURES_PER_LEVEL from ImageTemplatePyramid.cs:56, /// increase to increase the precision in expense of detection time-delay</param> /// <param name="userFunc">Input User Function for customization and diversity</param> /// <returns>List of templates.</returns> public static List <TemplatePyramid> fromFiles(String[] files, bool buildXMLTemplateFile = false, int angles = 360, int sizes = 1, bool CropToSqr = false, int[] maxFeaturesPerLevel = null, Func <TemplatePyramid, Gray <byte> [, ], TemplatePyramid> userFunc = null) { Console.WriteLine("Building templates from files..."); Gray <byte>[,] ResizedtemplatePic; var list = new List <TemplatePyramid>(); string resourceDir = Path.Combine(Directory.GetParent(Directory.GetCurrentDirectory()).FullName, "Resources"); //string[] files = Directory.GetFiles(resourceDir, fileName); if (files.Length == 0) { throw new Exception("NO FILE FOUND"); } object syncObj = new object(); foreach (var file in files) { int shortSide, SqrSide, inputWidth, inputHeight; float FileRatio = 1; Gray <byte>[,] preparedBWImage; for (int j = 0; j < sizes; j++) { Console.WriteLine("Size # " + j); try { preparedBWImage = ImageIO.LoadGray(file).Clone(); } catch { Console.WriteLine("Error occurs when loading " + file); continue; } FileRatio -= (float)0.01; int width = (int)(preparedBWImage.Width() * FileRatio); int height = (int)(preparedBWImage.Height() * FileRatio); if (FileRatio < 0) { Console.WriteLine("Too many sizes to build, Max 100"); FileRatio = 1; break; } DotImaging.Primitives2D.Size Nsize = new DotImaging.Primitives2D.Size(width, height); ResizedtemplatePic = ResizeExtensions_Gray.Resize(preparedBWImage, Nsize, Accord.Extensions.Imaging.InterpolationMode.NearestNeighbor); try { //var tp = TemplatePyramid.CreatePyramidFromPreparedBWImage(preparedBWImage, new FileInfo(file + " " + i * 10).Name, ImageAngle, maxNumberOfFeaturesPerLevel: maxFeaturesPerLevel); shortSide = (preparedBWImage.Width() < preparedBWImage.Height()) ? preparedBWImage.Width() : preparedBWImage.Height(); SqrSide = (int)(shortSide / Math.Sqrt(2)); inputWidth = CropToSqr ? SqrSide : preparedBWImage.Width(); inputHeight = CropToSqr ? SqrSide : preparedBWImage.Height(); rotateLoad(list, preparedBWImage, angles, inputWidth, inputHeight, false, maxFeaturesPerLevel, file, userFunc); } catch (Exception) { } } //} } if (buildXMLTemplateFile) { XMLTemplateSerializer <ImageTemplatePyramid <ImageTemplate>, ImageTemplate> .ToFile(list, Path.Combine(resourceDir, files[0].Substring(0, files[0].IndexOf(".")) + ".xml")); } return(list); }
/// <summary> /// Build template with the cemara /// /// State Machine----> /// int -> build template -> resize to find the best -> draw the template then comfirm by user -> /// rotate for angles ->done and return /// /// make sure the object is in green circle /// </summary> /// <param name="name">template name, default to "Template" if the name is null</param> /// <param name="templPyrs">the template list that to be used</param /// <param name="videoCapture">the video stream</param> /// <param name="pictureBox">the picture box of window form</param> /// <param name="minRatio">The ratio of smallest size to original, default to 0.4</param> /// /// <returns>nothing.</returns> public void TemplateCapture(ref List <TemplatePyramid> templPyrs, ImageStreamReader videoCapture, PictureBox pictureBox, string name = null, float minCalibrationRatio = 0.4f) { if (name == null) { name = "Template"; } #if runXML try { Console.WriteLine("Reading from existing Template Data"); templPyrs = fromXML(name); Cap = State.Done; } catch (Exception) { Console.WriteLine("\nTemplate NOT found! \n initiating camera..."); } #endif switch (Cap) { case State.Init: videoCapture.ReadTo(ref frame); if (frame == null) { return; } drawFrameWork(frame); pictureBox.Image = frame.ToBitmap(); //it will be just casted (data is shared) 24bpp color GC.Collect(); break; case State.BuildingTemplate: Console.WriteLine("building template"); videoCapture.ReadTo(ref frame); if (frame == null) { return; } templatePic = frame.ToGray(); //var list = new List<TemplatePyramid>(); try { if (templPyrs == null) { templPyrs = new List <TemplatePyramid>(); } rotateLoad(templPyrs, templatePic, 1, frame.Width(), frame.Height(), userFunc: validateFeatures); } catch (Exception) { Console.WriteLine("ERROR IN CREATING TEMPLATE!"); return; } Cap = State.Calibrate; break; case State.Calibrate: Console.WriteLine("calibrating template " + CabRatio + " " + templatePic.Width() * CabRatio); var bestRepresentatives = findObjects(frame, templPyrs); if (bestRepresentatives.Count == 0) { if (templPyrs.Count != 0) { templPyrs.RemoveAt(templPyrs.Count - 1); } CabRatio -= (float)0.01; int width = (int)(templatePic.Width() * CabRatio); int height = (int)(templatePic.Height() * CabRatio); if (CabRatio < minCalibrationRatio) { Console.WriteLine("Calibration failed"); CabRatio = 1; Cap = State.Init; } DotImaging.Primitives2D.Size Nsize = new DotImaging.Primitives2D.Size(width, height); ResiizedtemplatePic = ResizeExtensions_Gray.Resize(templatePic, Nsize, Accord.Extensions.Imaging.InterpolationMode.NearestNeighbor); try { templPyrs.Add(TemplatePyramid.CreatePyramidFromPreparedBWImage( ResiizedtemplatePic, new FileInfo(name + " #" + TPindex++).Name, 0)); } catch (Exception) { Console.WriteLine("ERROR IN CALIBRATING TEMPLATE!"); } } else { ResiizedtemplatePic = (ResiizedtemplatePic == null ? templatePic : ResiizedtemplatePic); CaptureFrame(templPyrs, videoCapture, pictureBox); drawFrameWork(frame); pictureBox.Image = frame.ToBitmap(); //it will be just casted (data is shared) 24bpp color Cap = State.Confirm; } break; case State.Confirm: Console.WriteLine("comfirm Template, press Y to continue, press R to retry, and other keys to abort"); string a = Console.ReadLine(); switch (a) { case "y": Cap = State.Rotate; break; case "r": templPyrs.RemoveAt(templPyrs.Count - 1); Cap = State.Init; break; default: Cap = State.Done; break; } //if (a == "y") Cap = State.Rotate; //else //{ // Cap = State.Init; //} break; case State.Rotate: int SqrSide = (int)(frame.Height() / Math.Sqrt(2)); templPyrs.AddRange(buildTemplate(ResiizedtemplatePic, SqrSide, SqrSide, false, totalAngles, totalSizes, 0.5f, null, validateFeatures)); //ResiizedtemplatePic, totalAngles, SqrSide, SqrSide, true, userFunc: validateFeatures)); Cap = State.ConfirmDone; break; case State.ConfirmDone: Console.WriteLine("Do you want to build a new template? press y to build another template, other keys to abort"); string OtherTemplate = Console.ReadLine(); if (OtherTemplate == "y" || OtherTemplate == "Y") { Cap = State.Init; } else { string resourceDir = Path.Combine(Directory.GetParent(Directory.GetCurrentDirectory()).FullName, "Resources"); XMLTemplateSerializer <ImageTemplatePyramid <ImageTemplate>, ImageTemplate> .ToFile(templPyrs, Path.Combine(resourceDir, name + ".xml")); Cap = State.Done; } break; //break; case State.Done: CaptureFrame(templPyrs, videoCapture, pictureBox); GC.Collect(); break; //break; } pictureBox.Image = frame.ToBitmap(); //it will be just casted (data is shared) 24bpp color }