Tutorial: Implementing Form Recognition with SDK
Learning Objectives
In this tutorial, you’ll learn how to:
- Set up and configure the Aspose.OMR Cloud SDK in your application
- Authenticate and establish connections to the cloud service
- Submit forms for recognition using native code instead of REST calls
- Process and utilize recognition results efficiently
- Implement robust error handling and retry logic
Prerequisites
Before starting this tutorial, make sure you have:
- Completed the previous tutorials in this series
- A development environment for your preferred programming language (.NET, Java, Python, etc.)
- Your Aspose Cloud API credentials (Client ID and Client Secret)
- Basic understanding of your programming language and package managers
- A sample filled OMR form and its corresponding recognition pattern
Understanding SDK Benefits
While you can directly use the Aspose.OMR Cloud REST API, the SDKs offer significant advantages:
- Simplified Integration: Native methods instead of complex HTTP requests
- Type Safety: Language-specific object models instead of raw JSON
- Efficiency: Automatic handling of authentication, connections, and serialization
- Reliability: Built-in error handling and best practices
- Updates: Regular maintenance to support new features and improvements
Step 1: Setting Up the SDK
Let’s start by installing the Aspose.OMR Cloud SDK for your preferred programming language:
For .NET (using NuGet)
# Using .NET CLI
dotnet add package Aspose.OMR-Cloud
# Using Package Manager Console
Install-Package Aspose.OMR-Cloud
Project Setup
Create a new project and add the required imports:
using Aspose.Omr.Cloud.Sdk.Api;
using Aspose.Omr.Cloud.Sdk.Model;
using System.IO;
using System.Collections.Generic;
Step 2: Configuring Authentication
The first step in any SDK implementation is to configure authentication with your Aspose Cloud credentials:
// Initialize the API with your credentials
RecognizeTemplateApi api = new RecognizeTemplateApi();
api.Configuration.ClientID = "YOUR_CLIENT_ID";
api.Configuration.ClientSecret = "YOUR_CLIENT_SECRET";
The SDK handles the token acquisition, renewal, and proper authorization headers automatically, saving you from writing this code yourself.
Step 3: Loading Form Resources
Next, let’s load the filled form image and its recognition pattern:
// Load the completed form
byte[] formImage = File.ReadAllBytes("completed_form.jpg");
// Load recognition pattern (previously generated .omr file)
byte[] pattern = File.ReadAllBytes("form_template.omr");
Step 4: Creating and Submitting the Recognition Task
Now, let’s create a recognition task and submit it to the Aspose.OMR Cloud service:
// Create recognition task with threshold and output format
OmrRecognizeTask task = new OmrRecognizeTask(
new List<byte[]> { formImage }, // Form images
pattern, // Recognition pattern
35, // Recognition threshold
S3DataType.Csv // Result format
);
// Submit the form for recognition
string taskId = api.PostRecognizeTemplate(task);
Console.WriteLine($"Form submitted successfully. Task ID: {taskId}");
In this example:
- We’re processing a single form image
- Setting the recognition threshold to 35%
- Requesting CSV output format
- The API returns a task ID for tracking
Step 5: Retrieving and Processing Results
After submitting the form, we need to fetch the results:
// Fetch recognition results
OMRRecognitionResponse result = api.GetRecognizeTemplate(taskId);
// Check for successful processing
if (result.ResponseStatusCode == "Ok" && result.Results.Count > 0)
{
// Save result to file
File.WriteAllBytes("recognition_results.csv", result.Results[0].Data);
Console.WriteLine("Results saved to recognition_results.csv");
// For demonstration, display the CSV content
string csvContent = System.Text.Encoding.UTF8.GetString(result.Results[0].Data);
Console.WriteLine("\nCSV Content Preview:");
Console.WriteLine(csvContent.Substring(0, Math.Min(csvContent.Length, 500)));
}
else
{
// Handle errors
if (result.Error != null && result.Error.Messages.Count > 0)
{
Console.WriteLine($"Recognition failed: {string.Join(", ", result.Error.Messages)}");
}
else
{
Console.WriteLine("Recognition failed with unknown error");
}
}
The SDK handles the base64 decoding of results automatically, returning the raw data that you can save or process directly.
Step 6: Complete Working Example
Let’s put it all together into a complete working example:
using Aspose.Omr.Cloud.Sdk.Api;
using Aspose.Omr.Cloud.Sdk.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
namespace AsposePomrRecognitionDemo
{
internal class Program
{
static void Main(string[] args)
{
try
{
// 1. Configure the API client
RecognizeTemplateApi api = new RecognizeTemplateApi();
api.Configuration.ClientID = "YOUR_CLIENT_ID";
api.Configuration.ClientSecret = "YOUR_CLIENT_SECRET";
Console.WriteLine("Authentication configured");
// 2. Load resources
byte[] formImage = File.ReadAllBytes("completed_form.jpg");
byte[] pattern = File.ReadAllBytes("form_template.omr");
Console.WriteLine("Resources loaded");
// 3. Submit form for recognition with 35% accuracy threshold
OmrRecognizeTask task = new OmrRecognizeTask(
new List<byte[]> { formImage },
pattern,
35,
S3DataType.Csv
);
string taskId = api.PostRecognizeTemplate(task);
Console.WriteLine($"Form submitted successfully. Task ID: {taskId}");
// 4. Wait a moment for processing (in production, implement proper polling)
Console.WriteLine("Waiting for processing to complete...");
Thread.Sleep(3000); // Wait 3 seconds
// 5. Fetch and process results
OMRRecognitionResponse result = api.GetRecognizeTemplate(taskId);
if (result.ResponseStatusCode == "Ok" && result.Results.Count > 0)
{
// Save result to file
File.WriteAllBytes("recognition_results.csv", result.Results[0].Data);
Console.WriteLine("Results saved to recognition_results.csv");
// Display CSV content
string csvContent = System.Text.Encoding.UTF8.GetString(result.Results[0].Data);
Console.WriteLine("\nCSV Content Preview:");
Console.WriteLine(csvContent.Substring(0, Math.Min(csvContent.Length, 500)));
// Process the CSV data (example: count filled answers)
string[] lines = csvContent.Split('\n');
int filledAnswers = 0;
for (int i = 1; i < lines.Length; i++) // Skip header row
{
string line = lines[i];
if (!string.IsNullOrEmpty(line) && line.Contains("\"selected\""))
{
filledAnswers++;
}
}
Console.WriteLine($"\nTotal marked answers: {filledAnswers}");
}
else if (result.ResponseStatusCode == "Processing")
{
Console.WriteLine("Form is still being processed. Try again later.");
}
else
{
// Handle errors
if (result.Error != null && result.Error.Messages.Count > 0)
{
Console.WriteLine($"Recognition failed: {string.Join(", ", result.Error.Messages)}");
}
else
{
Console.WriteLine("Recognition failed with unknown error");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
if (ex.InnerException != null)
{
Console.WriteLine($"Inner exception: {ex.InnerException.Message}");
}
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
}
Step 7: Implementing Production-Ready Features
For real-world applications, you’ll want to add these production-ready features:
Retry Logic
private static OMRRecognitionResponse FetchResultsWithRetry(
RecognizeTemplateApi api,
string taskId,
int maxRetries = 10,
int retryIntervalMs = 2000)
{
int attempts = 0;
while (attempts < maxRetries)
{
attempts++;
Console.WriteLine($"Attempt {attempts} to fetch results...");
OMRRecognitionResponse result = api.GetRecognizeTemplate(taskId);
if (result.ResponseStatusCode == "Ok" && result.Results.Count > 0)
{
return result;
}
else if (result.ResponseStatusCode == "Processing")
{
Console.WriteLine($"Processing in progress. Waiting {retryIntervalMs/1000} seconds...");
Thread.Sleep(retryIntervalMs);
continue;
}
else
{
// Return error result immediately
return result;
}
}
throw new TimeoutException($"Recognition timed out after {maxRetries} attempts");
}
Batch Processing
private static void ProcessBatchOfForms(RecognizeTemplateApi api, string directoryPath, string patternPath)
{
// Load pattern once
byte[] pattern = File.ReadAllBytes(patternPath);
// Process all JPEG and PNG files in directory
foreach (string filePath in Directory.GetFiles(directoryPath, "*.*")
.Where(f => f.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) ||
f.EndsWith(".jpeg", StringComparison.OrdinalIgnoreCase) ||
f.EndsWith(".png", StringComparison.OrdinalIgnoreCase)))
{
Console.WriteLine($"Processing {Path.GetFileName(filePath)}...");
try
{
byte[] formImage = File.ReadAllBytes(filePath);
OmrRecognizeTask task = new OmrRecognizeTask(
new List<byte[]> { formImage },
pattern,
35,
S3DataType.Csv
);
string taskId = api.PostRecognizeTemplate(task);
// Save results with filename based on original image
string resultPath = Path.Combine(
Path.GetDirectoryName(filePath),
Path.GetFileNameWithoutExtension(filePath) + "_results.csv"
);
// Fetch with retry logic
OMRRecognitionResponse result = FetchResultsWithRetry(api, taskId);
if (result.ResponseStatusCode == "Ok" && result.Results.Count > 0)
{
File.WriteAllBytes(resultPath, result.Results[0].Data);
Console.WriteLine($"Results saved to {resultPath}");
}
else
{
Console.WriteLine($"Failed to process {filePath}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error processing {filePath}: {ex.Message}");
}
}
}
Working with Other Programming Languages
Java Example
import com.aspose.omr.cloud.sdk.api.RecognizeTemplateApi;
import com.aspose.omr.cloud.sdk.model.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays;
public class OmrRecognitionExample {
public static void main(String[] args) {
try {
// Initialize API with credentials
RecognizeTemplateApi api = new RecognizeTemplateApi();
api.getConfig().setClientId("YOUR_CLIENT_ID");
api.getConfig().setClientSecret("YOUR_CLIENT_SECRET");
// Load resources
byte[] formImage = Files.readAllBytes(new File("completed_form.jpg").toPath());
byte[] pattern = Files.readAllBytes(new File("form_template.omr").toPath());
// Create recognition task
OmrRecognizeTask task = new OmrRecognizeTask();
task.setImages(Arrays.asList(formImage));
task.setOmrFile(pattern);
task.setRecognitionThreshold(35);
task.setOutputFormat(S3DataType.CSV);
// Submit for recognition
String taskId = api.postRecognizeTemplate(task);
System.out.println("Task ID: " + taskId);
// Wait for processing
Thread.sleep(3000);
// Fetch results
OMRRecognitionResponse result = api.getRecognizeTemplate(taskId);
// Process results
if ("Ok".equals(result.getResponseStatusCode()) && !result.getResults().isEmpty()) {
Files.write(new File("recognition_results.csv").toPath(),
result.getResults().get(0).getData());
System.out.println("Results saved to recognition_results.csv");
} else {
System.out.println("Recognition failed");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Python Example
import os
import time
import asposeocrcloud
from asposeocrcloud.apis.recognize_template_api import RecognizeTemplateApi
from asposeocrcloud.models.omr_recognize_task import OmrRecognizeTask
from asposeocrcloud.models.s3_data_type import S3DataType
# Configure API client
configuration = asposeocrcloud.Configuration(
client_id="YOUR_CLIENT_ID",
client_secret="YOUR_CLIENT_SECRET"
)
# Initialize API
api = RecognizeTemplateApi(configuration)
# Load resources
with open("completed_form.jpg", "rb") as image_file:
form_image = image_file.read()
with open("form_template.omr", "rb") as pattern_file:
pattern = pattern_file.read()
# Create and submit recognition task
task = OmrRecognizeTask(
images=[form_image],
omr_file=pattern,
recognition_threshold=35,
output_format=S3DataType.CSV
)
task_id = api.post_recognize_template(task)
print(f"Task ID: {task_id}")
# Wait for processing
time.sleep(3)
# Fetch results
response = api.get_recognize_template(task_id)
# Process results
if response.response_status_code == "Ok" and response.results:
with open("recognition_results.csv", "wb") as result_file:
result_file.write(response.results[0].data)
print("Results saved to recognition_results.csv")
else:
print("Recognition failed")
What You’ve Learned
In this tutorial, you’ve learned how to:
- Set up and configure the Aspose.OMR Cloud SDK for your preferred language
- Submit forms for recognition using native code and SDK methods
- Retrieve and process recognition results
- Implement production-ready features like retry logic and batch processing
- Build a complete working application for OMR form recognition
Next Steps
Now that you’ve completed this tutorial series, consider exploring these advanced topics:
- Creating multi-service applications that combine form generation and recognition
- Implementing a complete workflow from form design to data analysis
- Integrating OMR recognition with database storage and reporting systems
- Building web interfaces for form upload and result visualization
Further Practice
To reinforce your learning:
- Implement a complete form processing pipeline using the SDK
- Add result visualization and reporting features
- Create a web service that exposes form recognition capabilities to other applications
- Experiment with different output formats and post-processing strategies
Helpful Resources
Have questions about this tutorial? Visit our support forum for assistance.