/// <summary> /// Sets the specified image. /// </summary> /// <param name="image">Image to display.</param> public void SetImage(Bgr<byte>[,] image) { if (bmp == null || bmp.Width != image.Width() || bmp.Height != image.Height()) { bmp = new Bitmap(image.Width(), image.Height(), PixelFormat.Format24bppRgb); } BitmapData bmpData = bmp.Lock(); if (bmpData.BytesPerPixel != image.ColorInfo().Size) { bmpData.Dispose(); bmpData = null; bmp = new Bitmap(image.Width(), image.Height(), PixelFormat.Format24bppRgb); } bmpData = bmpData ?? bmp.Lock(); using (var uIm = image.Lock()) { Copy.UnsafeCopy2D(uIm.ImageData, bmpData.Data, uIm.Stride, bmpData.ScanWidth, uIm.Height); } bmpData.Dispose(); imageView.Image = bmp; if (ScaleForm) ClientSize = new Size(image.Width(), image.Height()); }
/// <summary> /// Draw the framework ( a small red circle, blue square and a big green circle) /// </summary> /// <param name="frame">the video frame that about to draw on</param> /// /// <returns>nothing.</returns> private static void drawFrameWork(Bgr <byte>[,] frame) { int RectWidth, RectHeight; int SqrSide; float RectRatio; int maxside = (int)(Math.Sqrt(frame.Width() * frame.Width() + frame.Height() * frame.Height())); RectRatio = (float)(frame.Height() > frame.Width() ? frame.Width() : frame.Height()) / maxside; //Console.WriteLine(frame.Height() + " "+ frame.Width() +" "+maxside + " " + RectRatio); RectWidth = (int)(frame.Width() * RectRatio); RectHeight = (int)(frame.Height() * RectRatio); DotImaging.Primitives2D.Rectangle rec = new DotImaging.Primitives2D.Rectangle((frame.Width() - RectWidth) / 2, (frame.Height() - RectHeight) / 2, (int)(frame.Width() * RectRatio), (int)(frame.Height() * RectRatio)); //frame.Draw(rec, Bgr<byte>.Blue, 2); rec.Width = rec.Height; rec.X = (frame.Width() - RectHeight) / 2; //frame.Draw(rec, Bgr<byte>.Red, 2); Circle cir = new Circle((frame.Width()) / 2, (frame.Height()) / 2, (int)(frame.Height() * RectRatio) / 2); //frame.Draw(cir, Bgr<byte>.Green, 2); cir.Radius = frame.Height() / 2; frame.Draw(cir, Bgr <byte> .Green, 2); SqrSide = (int)(frame.Height() / Math.Sqrt(2)); DotImaging.Primitives2D.Rectangle sqr = new DotImaging.Primitives2D.Rectangle((frame.Width() - SqrSide) / 2, (frame.Height() - SqrSide) / 2, SqrSide, SqrSide); frame.Draw(sqr, Bgr <byte> .Blue, 2); cir.Radius = SqrSide / 2; frame.Draw(cir, Bgr <byte> .Red, 2); }
/// <summary> /// Sets the specified image. /// </summary> /// <param name="image">Image to display.</param> public void SetImage(Bgr<byte>[,] image) { if (bmp == null || bmp.Width != image.Width() || bmp.Height != image.Height()) { bmp = new Bitmap(image.Width(), image.Height(), PixelFormat.Format24bppRgb); } using (BitmapData bmpData = bmp.Lock()) using (var uIm = image.Lock()) { Copy.UnsafeCopy2D(uIm.ImageData, bmpData.Data, uIm.Stride, bmpData.ScanWidth, uIm.Height); } PictureBox.Image = bmp; if (ScaleForm) ClientSize = new Size(image.Width(), image.Height()); }
/// <summary> /// Computes gradient orientations from the color image. Orientation from the channel which has the maximum gradient magnitude is taken as the orientation for a location. /// </summary> /// <param name="frame">Image.</param> /// <param name="magnitudeSqrImage">Squared magnitude image.</param> /// <param name="minValidMagnitude">Minimal valid magnitude.</param> /// <returns>Orientation image (angles are in degrees).</returns> public unsafe static Gray <int>[,] Compute(Bgr <byte>[,] frame, out Gray <int>[,] magnitudeSqrImage, int minValidMagnitude) { var minSqrMagnitude = minValidMagnitude * minValidMagnitude; var orientationImage = new Gray <int> [frame.Height(), frame.Width()]; var _magnitudeSqrImage = orientationImage.CopyBlank(); using (var uFrame = frame.Lock()) { ParallelLauncher.Launch(thread => { computeColor(thread, (byte *)uFrame.ImageData, uFrame.Stride, orientationImage, _magnitudeSqrImage, minSqrMagnitude); }, frame.Width() - 2 * kernelRadius, frame.Height() - 2 * kernelRadius); } magnitudeSqrImage = _magnitudeSqrImage; return(orientationImage); }
/// <summary> /// Creates and initializes new de-vignetting algorithm. /// </summary> /// <param name="image">Original image.</param> /// <param name="optimizeVignettingCentre"> /// True to optimize spatial vignetting position, false otherwise. /// <para>If set to false, the algorithm will perform significantly less number of steps.</para> /// </param> public Devignetting(Bgr <byte>[,] image, bool optimizeVignettingCentre = true) { var initialStep = new float[] { 5, 5, 5, image.Width() / 4, image.Height() / 4 }; var stepReduction = new float[] { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f }; var finalStep = new float[] { 1f / 256, 1f / 256, 1f / 256, 1, 1 }; var endParamIdx = DevignettingFunction.PARAMETER_COUNT - 1; if (!optimizeVignettingCentre) { endParamIdx -= 2; /*dX, dY*/ } optimizationAlg = new HillClimbingOptimization <DevignettingFunction, Bgr <byte> [, ]>(initialStep, stepReduction, finalStep, 0, endParamIdx); optimizationAlg.Initialize(DevignettingFunction.Empty, image); }
/// <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 }