Utilizza codici a barre 2D per allineare immagini in .NET/C#
Categoria blog: Barcode ; Forms processing ; .NET
15.05.2020
public static void Test() { AlignImages( new string[] { "BarcodeTemplateMatching_template1.png" }, new string[] { "BarcodeTemplateMatching_1_rotate90.png", "BarcodeTemplateMatching_1_scale-rotate150.png", "BarcodeTemplateMatching_1_scale-rotate180.png"}); } public static void AlignImages(string[] templates, string[] images) { // create barcode key zone recognizer BarcodeKeyZoneRecognizerCommand barcodeRecognizer = new BarcodeKeyZoneRecognizerCommand(); // set barcode reader settings barcodeRecognizer.Settings.ScanBarcodeTypes = Vintasoft.Barcode.BarcodeType.Aztec; barcodeRecognizer.Settings.ScanDirection = Vintasoft.Barcode.ScanDirection.Horizontal | Vintasoft.Barcode.ScanDirection.Vertical; barcodeRecognizer.Settings.AutomaticRecognition = true; // specify that image contains 3 barcodes barcodeRecognizer.Settings.ExpectedBarcodes = 3; // create an imprint generator, which is based on barcode key zones Vintasoft.Imaging.FormsProcessing.TemplateMatching.ImageImprintGeneratorCommand barcodeImprintGenerator = new Vintasoft.Imaging.FormsProcessing.TemplateMatching.ImageImprintGeneratorCommand(barcodeRecognizer); // create template matching command Vintasoft.Imaging.FormsProcessing.TemplateMatching.TemplateMatchingCommand templateMatchingCommand = new Vintasoft.Imaging.FormsProcessing.TemplateMatching.TemplateMatchingCommand(); // specify that the template matching command must use imprint generator, which is based on barcode key zones templateMatchingCommand.ImageImprintGenerator = barcodeImprintGenerator; // for each template image file foreach (string template in templates) { // add template image file to the templates of template matching command templateMatchingCommand.TemplateImages.Add(template); } // for each input image file foreach (string imageFilename in images) { // create input image using (Vintasoft.Imaging.VintasoftImage image = new Vintasoft.Imaging.VintasoftImage(imageFilename)) { // find a template for the image templateMatchingCommand.ExecuteInPlace(image); // get the image compare result Vintasoft.Imaging.FormsProcessing.TemplateMatching.ImageImprintCompareResult compareResult = templateMatchingCommand.Result.ImageCompareResult; // print image file name System.Console.WriteLine(imageFilename); // print the image comparison result System.Console.WriteLine(string.Format(" IsReliable ={0}", compareResult.IsReliable)); // if template for image is found if (compareResult.IsReliable) { // print the image comparison confidence System.Console.WriteLine(string.Format(" Confidence ={0}%", compareResult.Confidence * 100)); // print information about matrix, which defines image transformation relative to the template image System.Console.WriteLine(string.Format(" TransformMatrix ={0}", compareResult.TransformMatrix)); // create the template aligning command Vintasoft.Imaging.FormsProcessing.TemplateMatching.TemplateAligningCommand templateAligningCommand = new Vintasoft.Imaging.FormsProcessing.TemplateMatching.TemplateAligningCommand(); // specify that template aligning command must use matrix, which defines image transformation relative to the template image templateAligningCommand.CompareResult = compareResult; // apply the aligning command to the image templateAligningCommand.ExecuteInPlace(image); // save aligned image to a file image.Save(string.Format("{0}_result.png", System.IO.Path.GetFileNameWithoutExtension(imageFilename))); } System.Console.WriteLine(); } } }
/// <summary> /// Represents key zone based on recognized barcode. /// </summary> public class BarcodeKeyZone : Vintasoft.Imaging.FormsProcessing.TemplateMatching.KeyZone { #region Constructors /// <summary> /// Initializes a new instance of the <see cref="BarcodeKeyZone"/> class. /// </summary> /// <param name="barcodeInfo">The barcode information.</param> public BarcodeKeyZone(Vintasoft.Barcode.IBarcodeInfo barcodeInfo) : base() { _barcodeInfo = barcodeInfo; if (barcodeInfo is Vintasoft.Barcode.BarcodeInfo.AztecInfo) { // get the barcode center from barcode info _location = ((Vintasoft.Barcode.BarcodeInfo.AztecInfo)barcodeInfo).BulleyeCenter; } else { // calculate the barcode center _location = System.Drawing.PointF.Empty; System.Drawing.Point[] points = barcodeInfo.Region.GetPoints(); for (int i = 0; i < points.Length; i++) { _location.X += points[i].X; _location.Y += points[i].Y; } _location.X /= points.Length; _location.Y /= points.Length; } } /// <summary> /// Initializes a new instance of the <see cref="BarcodeKeyZone"/> class. /// </summary> /// <param name="barcodeInfo">The barcode information.</param> /// <param name="location">The location.</param> private BarcodeKeyZone(Vintasoft.Barcode.IBarcodeInfo barcodeInfo, System.Drawing.PointF location) : base() { _barcodeInfo = barcodeInfo; _location = location; } #endregion #region Properties System.Drawing.PointF _location; /// <summary> /// Gets the location of the key zone on the image. /// </summary> public override System.Drawing.PointF Location { get { return _location; } } Vintasoft.Barcode.IBarcodeInfo _barcodeInfo; /// <summary> /// Gets the barcode information. /// </summary> public Vintasoft.Barcode.IBarcodeInfo BarcodeInfo { get { return _barcodeInfo; } } #endregion #region Methods /// <summary> /// Applies a transformation to the key zone. /// </summary> /// <param name="m">The <see cref="Vintasoft.Imaging.AffineMatrix" /> /// that specifies the transformation to apply.</param> public override void Transform(Vintasoft.Imaging.AffineMatrix m) { if (m == null) return; _location = Vintasoft.Imaging.PointFAffineTransform.TransformPoint(m, _location); } /// <summary> /// Returns the similarity of specified <see cref="Vintasoft.Imaging.FormsProcessing.TemplateMatching.KeyZone" /> and the current key zone. /// </summary> /// <param name="zone">The <see cref="Vintasoft.Imaging.FormsProcessing.TemplateMatching.KeyZone" /> to compare with.</param> /// <returns> /// The similarity of specified keyzone and the current key zone in range from 0 to 1.<br /> /// 0 means that zones are absolutely NOT similar; /// 1 means that zones are perfectly similar. /// </returns> public override double CalculateSimilarity(Vintasoft.Imaging.FormsProcessing.TemplateMatching.KeyZone zone) { BarcodeKeyZone barcodeZone = zone as BarcodeKeyZone; if (barcodeZone == null) return 0; if (barcodeZone.BarcodeInfo.Value == BarcodeInfo.Value && barcodeZone.BarcodeInfo.BarcodeType == BarcodeInfo.BarcodeType) return 1; return 0; } /// <summary> /// Creates a new object that is a copy of the current instance. /// </summary> /// <returns>A new object that is a copy of this instance.</returns> public override object Clone() { return new BarcodeKeyZone(BarcodeInfo, Location); } #endregion }
/// <summary> /// Recognizes key zones, based on barcodes, on an image. /// </summary> public class BarcodeKeyZoneRecognizerCommand : Vintasoft.Imaging.FormsProcessing.TemplateMatching.KeyZoneRecognizerCommand { #region Constructors /// <summary> /// Initializes a new instance of the <see cref="BarcodeKeyZoneRecognizerCommand"/> class. /// </summary> public BarcodeKeyZoneRecognizerCommand() : base() { } #endregion #region Properties static System.Collections.ObjectModel.ReadOnlyCollection<Vintasoft.Imaging.PixelFormat> _supportedNativePixelFormats; /// <summary> /// Gets a list of supported pixel formats for this processing command. /// </summary> public override System.Collections.ObjectModel.ReadOnlyCollection<Vintasoft.Imaging.PixelFormat> SupportedNativePixelFormats { get { if (_supportedNativePixelFormats == null) { System.Collections.Generic.List<Vintasoft.Imaging.PixelFormat> supportedPixelFormats = new System.Collections.Generic.List<Vintasoft.Imaging.PixelFormat>(); supportedPixelFormats.Add(Vintasoft.Imaging.PixelFormat.BlackWhite); supportedPixelFormats.Add(Vintasoft.Imaging.PixelFormat.Bgr24); supportedPixelFormats.Add(Vintasoft.Imaging.PixelFormat.Bgr32); supportedPixelFormats.Add(Vintasoft.Imaging.PixelFormat.Indexed1); supportedPixelFormats.Add(Vintasoft.Imaging.PixelFormat.Indexed8); supportedPixelFormats.Add(Vintasoft.Imaging.PixelFormat.Gray8); _supportedNativePixelFormats = supportedPixelFormats.AsReadOnly(); } return _supportedNativePixelFormats; } } Vintasoft.Barcode.ReaderSettings _settings = new Vintasoft.Barcode.ReaderSettings(); /// <summary> /// Gets or sets the barcode reader settings. /// </summary> /// <value> /// The reader settings. /// </value> public Vintasoft.Barcode.ReaderSettings Settings { get { return _settings; } set { if (value == null) throw new System.ArgumentNullException(); _settings = value; } } #endregion #region Methods /// <summary> /// Creates a new <see cref="BarcodeKeyZoneRecognizerCommand"/> that is a copy of the current /// instance. /// </summary> /// <returns>A new <see cref="BarcodeKeyZoneRecognizerCommand"/> that is a copy of this /// instance.</returns> public override object Clone() { BarcodeKeyZoneRecognizerCommand recognizer = new BarcodeKeyZoneRecognizerCommand(); recognizer.IsNested = IsNested; recognizer.RegionOfInterest = RegionOfInterest; recognizer.Settings = Settings.Clone(); return recognizer; } /// <summary> /// Recognizes key zones in the specified rectangle of the specified image. /// </summary> /// <param name="image">The image where key zones must be searched.</param> /// <param name="rect">The region of interest on image.</param> /// <returns>An array of recognized key zones.</returns> protected override Vintasoft.Imaging.FormsProcessing.TemplateMatching.KeyZone[] Recognize(Vintasoft.Imaging.VintasoftImage image, System.Drawing.Rectangle rect) { Vintasoft.Barcode.BarcodeReader reader = new Vintasoft.Barcode.BarcodeReader(); reader.Settings = Settings.Clone(); reader.Settings.ScanRectangle = rect; using (System.Drawing.Bitmap bitmap = image.GetAsBitmap()) { Vintasoft.Barcode.IBarcodeInfo[] infos = reader.ReadBarcodes(bitmap); Vintasoft.Imaging.FormsProcessing.TemplateMatching.KeyZone[] result = new Vintasoft.Imaging.FormsProcessing.TemplateMatching.KeyZone[infos.Length]; for (int i = 0; i < infos.Length; i++) result[i] = new BarcodeKeyZone(infos[i]); return result; } } #endregion }