
El Reconocimiento de Marcas Ópticas (OMR) es un proceso automatizado para capturar y analizar datos marcados en un tipo especial de formulario de documento. Este tipo especial de documento puede ser marcado/completado por personas en formularios de encuestas, hojas de pruebas y otros documentos en papel. En este artículo, aprenderemos cómo desarrollar una aplicación de lector de hojas OMR basada en GUI utilizando C#. Nuestra solución tomará la imagen escaneada de la hoja OMR como entrada desde un disco local, luego reconocerá las marcas y finalmente exportará el número de registro marcado y las respuestas sombreadas en formato CSV. Después de seguir los pasos mencionados, tendremos nuestro Software de Reconocimiento de Marcas Ópticas (OMR) en C# y .NET. Así que comencemos.
El artículo cubrirá los siguientes temas:
- Características del Software de Reconocimiento de Marcas Ópticas (OMR) en C#
- API y Control de Interfaz de Usuario C# OMR .NET
- Pasos para Desarrollar Software OMR en C#
- Demostración del Software de Reconocimiento de Marcas Ópticas (OMR) en C#
- Descargar Código Fuente del Software OMR
Características del Software de Reconocimiento de Marcas Ópticas (OMR) en C#
Nuestro Software de Reconocimiento de Marcas Ópticas (OMR) tendrá las siguientes características:
- Ajustar interactivamente los parámetros de reconocimiento y observar su efecto en tiempo real. Podemos ajustar lo siguiente:
- Umbral de reconocimiento
- Zoom
- Mostrar/ocultar burbujas
- Seleccionar y cargar la imagen escaneada en los siguientes formatos:
- Reconocer las marcas ópticas en la imagen.
- Exportar resultados en CSV y guardarlos en su disco local.
API y Control de Interfaz de Usuario C# OMR .NET
La API de Aspose.OMR para .NET permite diseñar, crear y reconocer hojas de respuestas, pruebas, papeles de opción múltiple, cuestionarios, formularios de retroalimentación, encuestas y boletas. Además, proporciona un control de interfaz de usuario gráfica que se puede agregar a aplicaciones de interfaz de usuario .NET. Integraremos Aspose.OMR para control de interfaz de usuario en la aplicación de interfaz de usuario .NET para desarrollar una aplicación de escáner/lector OMR. Por favor, descargue el DLL de la API o instálelo usando NuGet.
PM> Install-Package Aspose.OMR
Pasos para Desarrollar Software OMR en C#
Podemos desarrollar una aplicación de escáner/lector OMR basada en GUI siguiendo los pasos que se indican a continuación:
- En primer lugar, crea un nuevo proyecto y selecciona la plantilla de proyecto WPF App (.NET Framework).

Cree un nuevo proyecto y seleccione la plantilla del proyecto.
- A continuación, en el cuadro de diálogo Configurar su nuevo proyecto, ingrese el Nombre del proyecto, elija la Ubicación y configure otros parámetros.

Configurar su Proyecto WPF
- Luego, abra Administrador de Paquetes NuGet e instale el paquete Aspose.OMR para .NET.

Instalar Aspose.OMR para .NET
- A continuación, agregue un nuevo archivo DialogHelper.cs al proyecto.

Agregar DialogHelper.cs
- Agregue el siguiente código al recién creado DialogHelper.cs.
internal class DialogHelper | |
{ | |
/// <summary> | |
/// The filter string for the dialog that opens template images. | |
/// </summary> | |
private static readonly string ImageFilesFilterPrompt = "Image files |*.jpg; *.jpeg; *.png; *.gif; *.tif; *.tiff;"; | |
/// <summary> | |
/// The filter string for the dialog that saves recognition results | |
/// </summary> | |
private static readonly string DataExportFilesFilterPrompt = "Comma-Separated Values (*.csv)" + " | *.csv"; | |
/// <summary> | |
/// Shows Open Image file dialog. | |
/// </summary> | |
/// <returns>Path to selected file, or <c>null</c> if no file was selected.</returns> | |
public static string ShowOpenImageDialog(string suggestedDir = null) | |
{ | |
OpenFileDialog dialog = new OpenFileDialog(); | |
return ShowDialog(dialog, ImageFilesFilterPrompt, suggestedDir); | |
} | |
/// <summary> | |
/// Shows Save Recognition Results file dialog. | |
/// </summary> | |
/// <returns>Path to selected file, or <c>null</c> if no file was selected.</returns> | |
public static string ShowSaveDataDialog(string suggestedName) | |
{ | |
SaveFileDialog dialog = new SaveFileDialog(); | |
return ShowDialog(dialog, DataExportFilesFilterPrompt, suggestedName); | |
} | |
/// <summary> | |
/// Displays given dialog and returns its result as a <c>string</c>. | |
/// </summary> | |
/// <param name="dialog">The dialog to show.</param> | |
/// <param name="filter">File type filter string.</param> | |
/// <param name="suggestedDir">Suggested dialog initial directory</param> | |
/// <param name="suggestedName">Suggested file name</param> | |
/// <returns>Path to selected file, or <c>null</c> if no file was selected.</returns> | |
private static string ShowDialog(FileDialog dialog, string filter, string suggestedDir = null, string suggestedName = null) | |
{ | |
string fileName = null; | |
dialog.Filter = filter; | |
dialog.RestoreDirectory = true; | |
if (suggestedName != null) | |
{ | |
dialog.FileName = suggestedName; | |
} | |
if (suggestedDir != null) | |
{ | |
dialog.InitialDirectory = suggestedDir; | |
} | |
bool? result = dialog.ShowDialog(); | |
if (result == true) | |
{ | |
fileName = dialog.FileName; | |
} | |
return fileName; | |
} | |
} |
- A continuación, actualice el archivo MainWindow.xaml con el siguiente contenido XAML.
<Window x:Class="OMR_APP.MainWindow" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
xmlns:local="clr-namespace:OMR_APP" | |
mc:Ignorable="d" | |
Title="Aspose OMR Demo" Height="880" Width="1100"> | |
<Grid Background="WhiteSmoke"> | |
<Grid.RowDefinitions> | |
<RowDefinition Height="40"></RowDefinition> | |
<RowDefinition Height="*"></RowDefinition> | |
</Grid.RowDefinitions> | |
<ToolBar Grid.Row="0" Background="LightGray"> | |
<TextBox Name="txtTemplatePath" Margin="5" Width="400" Height="30" Background="White" | |
HorizontalContentAlignment="Center" VerticalContentAlignment="Center"> | |
</TextBox> | |
<Button Margin="5" Width="100" Height="30" Background="White" | |
Content="Get control" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" | |
Click="GetButtonClicked"/> | |
<Separator/> | |
<Button Margin="5" Width="100" Height="30" Background="White" | |
Content="Select Image" Click="SelectImageClicked"/> | |
<Button Margin="5" Width="100" Height="30" Background="White" | |
Content="Recognize Image" Click="RecognizeImageClicked"/> | |
<Button Margin="5" Width="100" Height="30" Background="White" | |
Content="Export Results" Click="ExportResultsClicked"/> | |
</ToolBar> | |
<ContentControl Grid.Row="1" x:Name="CustomContentControl" | |
HorizontalAlignment="Center" VerticalAlignment="Center"/> | |
</Grid> | |
</Window> |
- Después de eso, reemplace el siguiente contenido en el archivo MainWindow.xaml.cs.
/// <summary> | |
/// Template for testing | |
/// </summary> | |
private static readonly string TemplateFilePath = @"C:\Files\OMR\Sheet.omr"; | |
/// <summary> | |
/// Path to the license Aspose.OMR.NET.lic file | |
/// </summary> | |
private static readonly string LicensePath = @""; | |
private CorrectionControl control; | |
public MainWindow() | |
{ | |
InitializeComponent(); | |
// Set and show template file path | |
txtTemplatePath.Text = TemplateFilePath; | |
// Set license, provide License file Path and uncomment to test full results | |
//License lic = new License(); | |
//lic.SetLicense(LicensePath); | |
} | |
public string UserImagePath { get; set; } | |
public string DataFolderPath { get; set; } | |
/// <summary> | |
/// Loads and displays CorrectionControl | |
/// </summary> | |
private void GetButtonClicked(object sender, RoutedEventArgs e) | |
{ | |
string path = txtTemplatePath.Text; | |
try | |
{ | |
OmrEngine engine = new OmrEngine(); | |
TemplateProcessor processor = engine.GetTemplateProcessor(path); | |
control = engine.GetCorrectionControl(processor); | |
CustomContentControl.Content = control; | |
control.Initialize(); | |
} | |
catch (Exception ex) | |
{ | |
MessageBox.Show(ex.Message,"Exception"); | |
} | |
} | |
/// <summary> | |
/// Select and display image | |
/// </summary> | |
private void SelectImageClicked(object sender, RoutedEventArgs e) | |
{ | |
if (control == null) | |
{ | |
return; | |
} | |
string imagePath = DialogHelper.ShowOpenImageDialog(this.DataFolderPath); | |
if (string.IsNullOrEmpty(imagePath)) | |
{ | |
return; | |
} | |
this.UserImagePath = imagePath; | |
control.LoadAndDisplayImage(imagePath); | |
} | |
/// <summary> | |
/// Recognize loaded image | |
/// </summary> | |
private void RecognizeImageClicked(object sender, RoutedEventArgs e) | |
{ | |
if (control == null) | |
{ | |
return; | |
} | |
control.RecognizeImage(); | |
} | |
/// <summary> | |
/// Export results to CSV | |
/// </summary> | |
private void ExportResultsClicked(object sender, RoutedEventArgs e) | |
{ | |
if (control == null) | |
{ | |
return; | |
} | |
string imageName = Path.GetFileNameWithoutExtension(this.UserImagePath); | |
string path = DialogHelper.ShowSaveDataDialog(imageName); | |
if (string.IsNullOrEmpty(path)) | |
{ | |
return; | |
} | |
control.ExportResults(path); | |
MessageBox.Show("The exported resultant CSV file can be found here : " + path, "Operation Successful"); | |
} |
- Finalmente, ejecute la aplicación.
Demostración del Software de Reconocimiento de Marcas Ópticas (OMR) en C#
La siguiente es la demostración de la aplicación de escáner/lector OMR que acabamos de crear.

Demostración del Software OMR
Descargar Código Fuente del Software OMR en C# .NET
Puede descargar el código fuente completo de la aplicación de escáner OMR en C# desde GitHub.
Obtener una Licencia Gratuita
Puede obtener una licencia temporal gratuita para probar la biblioteca sin limitaciones de evaluación.
Conclusión
En este artículo, hemos aprendido cómo
- integrar Aspose.OMR para control de interfaz de usuario en la aplicación .NET;
- desarrollar una aplicación de lector de hojas OMR en C#.
Además, puede aprender más sobre la API de Aspose.OMR para .NET utilizando la documentación. En caso de cualquier ambigüedad, no dude en contactarnos en nuestro foro.