diff --git a/openalprnet-windemo/Form1.Designer.cs b/openalprnet-windemo/Form1.Designer.cs
new file mode 100644
index 0000000..56ea8e7
--- /dev/null
+++ b/openalprnet-windemo/Form1.Designer.cs
@@ -0,0 +1,192 @@
+namespace openalprnet_windemo
+{
+ partial class Form1
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.btnDetect = new System.Windows.Forms.Button();
+ this.picLicensePlate = new System.Windows.Forms.PictureBox();
+ this.picOriginal = new System.Windows.Forms.PictureBox();
+ this.lbxPlates = new System.Windows.Forms.ListBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.label2 = new System.Windows.Forms.Label();
+ this.label3 = new System.Windows.Forms.Label();
+ this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
+ this.label4 = new System.Windows.Forms.Label();
+ this.rbUSA = new System.Windows.Forms.RadioButton();
+ this.rbEU = new System.Windows.Forms.RadioButton();
+ ((System.ComponentModel.ISupportInitialize)(this.picLicensePlate)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.picOriginal)).BeginInit();
+ this.SuspendLayout();
+ //
+ // btnDetect
+ //
+ this.btnDetect.Location = new System.Drawing.Point(830, 25);
+ this.btnDetect.Name = "btnDetect";
+ this.btnDetect.Size = new System.Drawing.Size(291, 37);
+ this.btnDetect.TabIndex = 0;
+ this.btnDetect.Text = "Detect License Plate";
+ this.btnDetect.UseVisualStyleBackColor = true;
+ this.btnDetect.Click += new System.EventHandler(this.button1_Click);
+ //
+ // picLicensePlate
+ //
+ this.picLicensePlate.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.picLicensePlate.Location = new System.Drawing.Point(827, 403);
+ this.picLicensePlate.Name = "picLicensePlate";
+ this.picLicensePlate.Size = new System.Drawing.Size(294, 123);
+ this.picLicensePlate.TabIndex = 1;
+ this.picLicensePlate.TabStop = false;
+ //
+ // picOriginal
+ //
+ this.picOriginal.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.picOriginal.Location = new System.Drawing.Point(12, 25);
+ this.picOriginal.Name = "picOriginal";
+ this.picOriginal.Size = new System.Drawing.Size(809, 501);
+ this.picOriginal.TabIndex = 2;
+ this.picOriginal.TabStop = false;
+ //
+ // lbxPlates
+ //
+ this.lbxPlates.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lbxPlates.FormattingEnabled = true;
+ this.lbxPlates.Location = new System.Drawing.Point(827, 81);
+ this.lbxPlates.Name = "lbxPlates";
+ this.lbxPlates.Size = new System.Drawing.Size(294, 303);
+ this.lbxPlates.TabIndex = 3;
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(12, 9);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(76, 13);
+ this.label1.TabIndex = 4;
+ this.label1.Text = "Source Image:";
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(827, 387);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(96, 13);
+ this.label2.TabIndex = 5;
+ this.label2.Text = "License Plate ROI:";
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Location = new System.Drawing.Point(827, 65);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(124, 13);
+ this.label3.TabIndex = 6;
+ this.label3.Text = "Matched License Plates:";
+ //
+ // openFileDialog
+ //
+ this.openFileDialog.Filter = "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif;" +
+ " *.png|All files (*.*)|*.*";
+ //
+ // label4
+ //
+ this.label4.AutoSize = true;
+ this.label4.Location = new System.Drawing.Point(827, 9);
+ this.label4.Name = "label4";
+ this.label4.Size = new System.Drawing.Size(44, 13);
+ this.label4.TabIndex = 7;
+ this.label4.Text = "Region:";
+ //
+ // rbUSA
+ //
+ this.rbUSA.AutoSize = true;
+ this.rbUSA.Checked = true;
+ this.rbUSA.Location = new System.Drawing.Point(878, 7);
+ this.rbUSA.Name = "rbUSA";
+ this.rbUSA.Size = new System.Drawing.Size(40, 17);
+ this.rbUSA.TabIndex = 8;
+ this.rbUSA.TabStop = true;
+ this.rbUSA.Text = "US";
+ this.rbUSA.UseVisualStyleBackColor = true;
+ //
+ // rbEU
+ //
+ this.rbEU.AutoSize = true;
+ this.rbEU.Location = new System.Drawing.Point(924, 7);
+ this.rbEU.Name = "rbEU";
+ this.rbEU.Size = new System.Drawing.Size(40, 17);
+ this.rbEU.TabIndex = 9;
+ this.rbEU.Text = "EU";
+ this.rbEU.UseVisualStyleBackColor = true;
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.BackColor = System.Drawing.Color.White;
+ this.ClientSize = new System.Drawing.Size(1128, 538);
+ this.Controls.Add(this.rbEU);
+ this.Controls.Add(this.rbUSA);
+ this.Controls.Add(this.label4);
+ this.Controls.Add(this.label3);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.lbxPlates);
+ this.Controls.Add(this.picOriginal);
+ this.Controls.Add(this.picLicensePlate);
+ this.Controls.Add(this.btnDetect);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "Form1";
+ this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "OpenALPR-Net Demo";
+ this.Load += new System.EventHandler(this.Form1_Load);
+ ((System.ComponentModel.ISupportInitialize)(this.picLicensePlate)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.picOriginal)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button btnDetect;
+ private System.Windows.Forms.PictureBox picLicensePlate;
+ private System.Windows.Forms.PictureBox picOriginal;
+ private System.Windows.Forms.ListBox lbxPlates;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.OpenFileDialog openFileDialog;
+ private System.Windows.Forms.Label label4;
+ private System.Windows.Forms.RadioButton rbUSA;
+ private System.Windows.Forms.RadioButton rbEU;
+ }
+}
+
diff --git a/openalprnet-windemo/Form1.cs b/openalprnet-windemo/Form1.cs
new file mode 100644
index 0000000..807474e
--- /dev/null
+++ b/openalprnet-windemo/Form1.cs
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2015 Dr. Masroor Ehsan
+ *
+ * This file is part of OpenAlpr.Net.
+ *
+ * OpenAlpr.Net is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License
+ * version 3 as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Windows.Forms;
+using openalprnet;
+
+namespace openalprnet_windemo
+{
+ public partial class Form1 : Form
+ {
+ public Form1()
+ {
+ InitializeComponent();
+ }
+
+ public static string AssemblyDirectory
+ {
+ get
+ {
+ var codeBase = Assembly.GetExecutingAssembly().CodeBase;
+ var uri = new UriBuilder(codeBase);
+ var path = Uri.UnescapeDataString(uri.Path);
+ return Path.GetDirectoryName(path);
+ }
+ }
+
+ public Rectangle boundingRectangle(List points)
+ {
+ // Add checks here, if necessary, to make sure that points is not null,
+ // and that it contains at least one (or perhaps two?) elements
+
+ var minX = points.Min(p => p.X);
+ var minY = points.Min(p => p.Y);
+ var maxX = points.Max(p => p.X);
+ var maxY = points.Max(p => p.Y);
+
+ return new Rectangle(new Point(minX, minY), new Size(maxX - minX, maxY - minY));
+ }
+
+ private static Image cropImage(Image img, Rectangle cropArea)
+ {
+ var bmpImage = new Bitmap(img);
+ return bmpImage.Clone(cropArea, bmpImage.PixelFormat);
+ }
+
+ public static Bitmap combineImages(List images)
+ {
+ //read all images into memory
+ Bitmap finalImage = null;
+
+ try
+ {
+ int width = 0;
+ int height = 0;
+
+ foreach (var bmp in images)
+ {
+ width += bmp.Width;
+ height = bmp.Height > height ? bmp.Height : height;
+ }
+
+ //create a bitmap to hold the combined image
+ finalImage = new System.Drawing.Bitmap(width, height);
+
+ //get a graphics object from the image so we can draw on it
+ using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(finalImage))
+ {
+ //set background color
+ g.Clear(System.Drawing.Color.Black);
+
+ //go through each image and draw it on the final image
+ int offset = 0;
+ foreach (System.Drawing.Bitmap image in images)
+ {
+ g.DrawImage(image,
+ new System.Drawing.Rectangle(offset, 0, image.Width, image.Height));
+ offset += image.Width;
+ }
+ }
+
+ return finalImage;
+ }
+ catch (Exception ex)
+ {
+ if (finalImage != null)
+ finalImage.Dispose();
+
+ throw ex;
+ }
+ finally
+ {
+ //clean up memory
+ foreach (System.Drawing.Bitmap image in images)
+ {
+ image.Dispose();
+ }
+ }
+ }
+
+ private void button1_Click(object sender, EventArgs e)
+ {
+ if (openFileDialog.ShowDialog(this) == DialogResult.OK)
+ {
+ processImageFile(openFileDialog.FileName);
+ }
+ }
+
+ private void processImageFile(string fileName)
+ {
+ resetControls();
+ var region = rbUSA.Checked ? "us" : "eu";
+ using (var alpr = new AlprNet(region, Path.Combine(AssemblyDirectory, "openalpr.conf")))
+ {
+ picOriginal.ImageLocation = fileName;
+ picOriginal.Load();
+
+ var results = alpr.recognize(fileName);
+
+ List images = new List(results.Count());
+ var i = 1;
+ foreach (var result in results)
+ {
+ var rect = boundingRectangle(result.plate_points);
+ var img = Image.FromFile(fileName);
+ var cropped = cropImage(img, rect);
+ images.Add(cropped);
+
+ lbxPlates.Items.Add("\t\t-- Plate #" + i++ + " --");
+ foreach (var plate in result.topNPlates)
+ {
+ lbxPlates.Items.Add(string.Format(@"{0} {1}% {2}",
+ plate.characters.PadRight(12),
+ plate.overall_confidence.ToString("N1").PadLeft(8),
+ plate.matches_template.ToString().PadLeft(8)));
+ }
+ }
+
+ if (images.Any())
+ {
+ picLicensePlate.Image = combineImages(images);
+ }
+ }
+ }
+
+ private void resetControls()
+ {
+ picOriginal.Image = null;
+ picLicensePlate.Image = null;
+ lbxPlates.Items.Clear();
+ }
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+ resetControls();
+ }
+ }
+}
\ No newline at end of file
diff --git a/openalprnet-windemo/Form1.resx b/openalprnet-windemo/Form1.resx
new file mode 100644
index 0000000..a3d5a63
--- /dev/null
+++ b/openalprnet-windemo/Form1.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/openalprnet-windemo/Program.cs b/openalprnet-windemo/Program.cs
new file mode 100644
index 0000000..b5cd5ed
--- /dev/null
+++ b/openalprnet-windemo/Program.cs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015 Dr. Masroor Ehsan
+ *
+ * This file is part of OpenAlpr.Net.
+ *
+ * OpenAlpr.Net is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License
+ * version 3 as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace openalprnet_windemo
+{
+ static class Program
+ {
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1());
+ }
+ }
+}
diff --git a/openalprnet-windemo/Properties/AssemblyInfo.cs b/openalprnet-windemo/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..4eccafe
--- /dev/null
+++ b/openalprnet-windemo/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("openalprnet-windemo")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("openalprnet-windemo")]
+[assembly: AssemblyCopyright("Copyright © 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("b1ab96ca-afe9-497d-9aa0-74ace195dfca")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/openalprnet-windemo/Properties/Resources.Designer.cs b/openalprnet-windemo/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..5375cf1
--- /dev/null
+++ b/openalprnet-windemo/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.34209
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace openalprnet_windemo.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("openalprnet_windemo.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/openalprnet-windemo/Properties/Resources.resx b/openalprnet-windemo/Properties/Resources.resx
new file mode 100644
index 0000000..ffecec8
--- /dev/null
+++ b/openalprnet-windemo/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/openalprnet-windemo/Properties/Settings.Designer.cs b/openalprnet-windemo/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..b44f110
--- /dev/null
+++ b/openalprnet-windemo/Properties/Settings.Designer.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.34209
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace openalprnet_windemo.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/openalprnet-windemo/Properties/Settings.settings b/openalprnet-windemo/Properties/Settings.settings
new file mode 100644
index 0000000..abf36c5
--- /dev/null
+++ b/openalprnet-windemo/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/openalprnet-windemo/app.config b/openalprnet-windemo/app.config
new file mode 100644
index 0000000..cb2586b
--- /dev/null
+++ b/openalprnet-windemo/app.config
@@ -0,0 +1,3 @@
+
+
+
diff --git a/openalprnet-windemo/openalprnet-windemo.csproj b/openalprnet-windemo/openalprnet-windemo.csproj
new file mode 100644
index 0000000..5032e2c
--- /dev/null
+++ b/openalprnet-windemo/openalprnet-windemo.csproj
@@ -0,0 +1,96 @@
+
+
+
+ Debug
+ x86
+ 8.0.30703
+ 2.0
+ {C7863A14-55D2-4389-9072-04AA6E30AAD1}
+ WinExe
+ Properties
+ openalprnet_windemo
+ openalprnet-windemo
+ v4.0
+
+
+ 512
+
+
+ x86
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ x86
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Form
+
+
+ Form1.cs
+
+
+
+
+ Form1.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+ True
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+
+
+ {4044340C-C435-4A1F-8F12-0806C38AE3B6}
+ openalpr-net
+
+
+
+
+
\ No newline at end of file