Microsoft Vision API unable to process OCR - ocr

I am using the project from https://github.com/microsoft/cognitive-vision-windows, I am able to upload image but the OCR is unable to be processed. It just stays on "Performing OCR..." Same for other functions except "Recognize Handwriting Text"
//
// Perform OCR on the given url
//
Log("Calling VisionServiceClient.RecognizeTextAsync()...");
OcrResults ocrResult = await VisionServiceClient.RecognizeTextAsync(imageUrl, language);
return ocrResult;
// -----------------------------------------------------------------------
// KEY SAMPLE CODE ENDS HERE
// -----------------------------------------------------------------------
}
/// <summary>
/// Perform the work for this scenario
/// </summary>
/// <param name="imageUri">The URI of the image to run against the scenario</param>
/// <param name="upload">Upload the image to Project Oxford if [true]; submit the Uri as a remote url if [false];</param>
/// <returns></returns>
protected override async Task DoWork(Uri imageUri, bool upload)
{
_status.Text = "Performing OCR...";
string languageCode = (languageComboBox.SelectedItem as RecognizeLanguage).ShortCode;
//
// Either upload an image, or supply a url
//
OcrResults ocrResult;
if (upload)
{
ocrResult = await UploadAndRecognizeImage(imageUri.LocalPath, languageCode);
}
else
{
ocrResult = await RecognizeUrl(imageUri.AbsoluteUri, languageCode);
}
_status.Text = "OCR Done";
//
// Log analysis result in the log window
//
Log("");
Log("OCR Result:");
LogOcrResults(ocrResult);
}

Related

Why does OneNote API pages request return empty page list?

Few days ago our applications (iOS, Android and Windows) stopped getting the list of Pages from Microsoft OneNote via OneNote API request https://www.onenote.com/api/v1.0/me/notes/pages. Request returns HTTP OK and empty content.
Source code Windows UWP appliaction C#-XAML (from Microsoft OneNote API example https://github.com/OneNoteDev/OneNoteAPISampleWinUniversal)
public static string GET_PAGES_REQEST = APIENDPOINT + "sections/{0}/pages";
public const string APIENDPOINT = "https://www.onenote.com/api/v1.0/me/notes/";
public const string AUTHMETHOD = "Bearer";
public const string APPJSON = "application/json";
/// <summary>
/// Get meta data for ALL pages under a given section
/// </summary>
/// <param name="sectionId">Id of the section for which the page are returned</param>
/// <param name="token">Authentication token</param>
/// <param name="isEncryptedOnly">View encrypted only notes</param>
/// <remarks> The sectionId can be fetched by querying the user's sections (e.g. GET https://www.onenote.com/api/v1.0/sections ).
/// NOTE: Using this approach, you can still query pages with ALL the different params shown in examples above.
/// </remarks>
/// <returns>The converted HTTP response message</returns>
public static async Task<List<PageApiResponse>> GetListAsync(string sectionId, string token, bool isEncryptedOnly)
{
var client = new HttpClient();
// Note: API only supports JSON response.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(Common.APPJSON));
//client.DefaultRequestHeaders.Add("FavorDataRecency", "true");
// Not adding the Authentication header would produce an unauthorized call and the API will return a 401
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue
(
Common.AUTHMETHOD, token
);
// Prepare an HTTP GET request to the Pages endpoint
var getMessage = new HttpRequestMessage
(
HttpMethod.Get,
isEncryptedOnly ?
String.Format(Common.GET_PAGES_ENCRYPTED_REQEST, sectionId) :
String.Format(Common.GET_PAGES_REQEST, sectionId)
);
HttpResponseMessage response = await client.SendAsync(getMessage);
string body = await response.Content.ReadAsStringAsync();
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception(Errors.TranslateError(response));
var content = JObject.Parse(body);
return JsonConvert.DeserializeObject<List<PageApiResponse>>(content["value"].ToString());
}
sectionId and token is correct. isEncryptedOnly = false;
Notebooks and Sections work fine. Anybody can help me?

Serilog HTTP Sink custom formatting for Logstash

I am using Serilog HTTP sink for logging to Logstash in my .Net Core Project. In startup.cs I have following code to enable serilog.
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.WriteTo.Http("http://mylogstashhost.com:5000").Enrich.WithProperty("user", "xxx").Enrich.WithProperty("serviceName", "yyy")
.MinimumLevel.Warning()
.CreateLogger();
And this code sends logs to the given http address. I can see on fiddler that following json is being posted to the logstash and logstash returns "ok" message.
{"events":[{"Timestamp":"2018-10-19T18:16:27.6561159+01:00","Level":"Warning","MessageTemplate":"abc","RenderedMessage":"abc","user":"xxx","serviceName":"yyy","Properties":{"ActionId":"b313b8ed-0baf-4d75-a6e2-f0dbcb941f67","ActionName":"MyProject.Controllers.HomeController.Index","RequestId":"0HLHLQMV1EBCJ:00000003","RequestPath":"/"}}]}
But when I checked on Kibana, I can not see this log. I tried to figure out what causes it and i realized that if I send the json as following format I can see the Log.
{"Timestamp":"2018-10-19T18:16:27.6561159+01:00","Level":"Warning","MessageTemplate":"abc","RenderedMessage":"abc","user":"xxx","serviceName":"yyy","Properties":{"ActionId":"b313b8ed-0baf-4d75-a6e2-f0dbcb941f67","ActionName":"MyProject.Controllers.HomeController.Index" ,"RequestId":"0HLHLQMV1EBCJ:00000003","RequestPath":"/"}}
So Logstash doesnt like the event to be in Events{} and also it wants "user" and "ServiceName" tags out of "Properties". Is there a way to format my Json like this?
Ok after some research and help, basically to achieve custom formats, one should implement interfaces like ITextFormatter, BatchFormatter etc.
I could achieve the format i need, by modifying ArrayBatchFormatter a little:
public class MyFormat : BatchFormatter
{
/// <summary>
/// Initializes a new instance of the <see cref="ArrayBatchFormatter"/> class.
/// </summary>
/// <param name="eventBodyLimitBytes">
/// The maximum size, in bytes, that the JSON representation of an event may take before it
/// is dropped rather than being sent to the server. Specify null for no limit. Default
/// value is 256 KB.
/// </param>
public MyFormat(long? eventBodyLimitBytes = 256 * 1024): base(eventBodyLimitBytes)
{
}
/// <summary>
/// Format the log events into a payload.
/// </summary>
/// <param name="logEvents">
/// The events to format.
/// </param>
/// <param name="output">
/// The payload to send over the network.
/// </param>
public override void Format(IEnumerable<string> logEvents, TextWriter output)
{
if (logEvents == null) throw new ArgumentNullException(nameof(logEvents));
if (output == null) throw new ArgumentNullException(nameof(output));
// Abort if sequence of log events is empty
if (!logEvents.Any())
{
return;
}
output.Write("[");
var delimStart = string.Empty;
foreach (var logEvent in logEvents)
{
if (string.IsNullOrWhiteSpace(logEvent))
{
continue;
}
int index = logEvent.IndexOf("{");
string adjustedString = "{\"user\":\"xxx\",\"serviceName\" : \"yyy\"," + logEvent.Substring(1);
if (CheckEventBodySize(adjustedString))
{
output.Write(delimStart);
output.Write(adjustedString);
delimStart = ",";
}
}
output.Write("]");
}
}
I would like to extend #nooaa answer with this variation. Instead of manipulating the string to add new objects, I would suggest using Newtonsoft.Json.Linq. This way you can append, add or remove existing properties of the object itself.
Also, instead of doing output.write after each event, you can combine all the output from the events and do output.write once at the end (a bit of performance)
public override void Format(IEnumerable<string> logEvents, TextWriter output)
{
if (logEvents == null) throw new ArgumentNullException(nameof(logEvents));
if (output == null) throw new ArgumentNullException(nameof(output));
// Abort if sequence of log events is empty
if (!logEvents.Any())
{
return;
}
List<object> updatedEvents = new List<object>();
foreach (string logEvent in logEvents)
{
if (string.IsNullOrWhiteSpace(logEvent))
{
continue;
}
// Parse the log event
var obj = JObject.Parse(logEvent);
// Add New entries
obj["#source_host"] = obj["fields"]["MachineName"].Value<string>().ToLower();
// Remove any entries you are not interested in
((JObject)obj["fields"]).Remove("MachineName");
// Default tags for any log that goes out of your app.
obj["#tags"] = new JArray() { "appName", "api" };
// Additional tags from end points (custom based on routes)
if (obj["fields"]["tags"] != null)
{
((JArray)obj["#tags"]).Merge((JArray)obj["fields"]["tags"]);
((JObject)obj["fields"]).Remove("tags");
}
updatedEvents.Add(obj);
}
output.Write(JsonConvert.SerializeObject(updatedEvents));
}
Update
Release Notes v8.0.0
With latest release, you dont override the method anymore.
namespace Serilog.Sinks.Http.BatchFormatters {
public class MyCustomFormatter: IBatchFormatter {
public void Format(IEnumerable<string> logEvents, TextWriter output) {
...
}
}
}
you don't provide any Contructors for it either.
Add queueLimitBytes along with batchFormatter and textFormatter
WriteTo.Http(new Uri(),
batchFormatter: new MyCustomFormatter(),
queueLimitBytes: 50 * ByteSize.MB,
textFormatter: new ElasticsearchJsonFormatter());

Pubnub SDK translation from Unity to Javascript Function?

In Javascript its basically:
pubnub.publish({
channel: 'Chatbox',
message: {
username: 'username',
text: message
}
});
pubnub.subscribe({
channel: 'Chatbox',
message: handleMessage
});
function handleMessage(message) {
var messageEl = $("<li class='message'>"
+ "<span class='username'>" + message.username + ": </span>"
+ message.text
+ "</li>");
messageList.append(messageEl);
messageList.listview('refresh');
In Unity instead of using message.username. Unity gives a dictionary. Unity seems to be the more complicated one so I would like to translate the unity from string url to publish sdk, if possible.
Here is the UNity Wrapper
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PubNubWrapper : MonoBehaviour
{
public static PubNubWrapper instance;
public string PublishKey = "";
public string SubscribeKey = "";
private Dictionary<string, System.Action<string>> channelMessageHandlers = new Dictionary<string, System.Action<string>>();
private string timeToken = "o";
void Awake()
{
instance = this;
// Debug.Log("Received message: ");
}
//send the ported message
/// <summary>
/// The Publish function creates a new JSON string by creating a WWW object. The WWW object is the object
/// making the requests to the PubNub Server. Part of the Publish, Subscribe and Unsubscribe requests for web services
/// </summary>
/// <param name="message"></param>
/// <param name="channel"></param>
public void Publish(string message, string channel)
{
//esc the message so we can put it into webservices
string escapedMessage = WWW.EscapeURL(message).Replace("+", "%20"); // UNity's URL escaping function replaces spaces '+'
//form the URL
//http://pubsub/pubnub.com
// /publish
// /[publishKey]
// /[subscribe key]
// /[o
// /[channel name]
// /o
// /[JSON message data]
string url =
"http://pubsub.pubnub.com" +"/publish" +"/" + PublishKey +"/" + SubscribeKey +"/o" +"/" + channel +"/o" +"/\"" + escapedMessage + "\"";
//make the request with a newly created WWW object
WWW www = new WWW(url);
}
/// <summary>
/// Subscribe creates an open port to listen to published messages sent with a JSON string
/// </summary>
/// <param name="channel"> N/a </param>
/// <param name="messageHandler"> N/a </param>
public void Subscribe(string channel, System.Action<string> messageHandler)
{
channelMessageHandlers.Add(channel, messageHandler);
StartCoroutine(doSubscribe(channel));
}
/// <summary>
/// The doSubscribe is the action for the channel to listen to for published messages
/// </summary>
/// <param name="channel"></param>
/// <returns></returns>
IEnumerator doSubscribe(string channel)
{
//The mssage handler here will again be JSON for parsing
while (channelMessageHandlers.ContainsKey(channel))
{
// form the URL
// /http://pubsub.pubnub.com
// /subscribe
// /[subscribe key here]
// / [channel key here]
// /o
// /[time token here]
string url =
"http://pubsub.pubnub.com" +
"/subscribe" +
"/" + SubscribeKey +
"/" + channel +
"/o" +
"/" + timeToken;
// make the request
WWW www = new WWW(url);
//in Unity we can yield
// a WWW object whic makes Unity "pause"
// a subroutine until the request has either encountered and error or done
yield return www;
//www.error is a string
// it will either be null/empty if there is no error, or it
// will contain the error message if there was one
if (!string.IsNullOrEmpty(www.error))
{
//log the error to the console
Debug.LogWarning("Subscribe failed: " + www.error);
//unsibscribe from the channel automatically
// yield break causes Unity to stop exiting this
// coroutine. It is equivalent to a return function
yield break;
}
//parse the JSON response from the client from subscription
string newToken;
string[] newMessages = PubNubUtils.ParseSubscribeResponse(
www.text, out newToken);
timeToken = newToken;
//make sure there is a still a subscription
if (channelMessageHandlers.ContainsKey(channel))
{
// handle each message separately
for (int i = 0; i < newMessages.Length; i++)
{
channelMessageHandlers[channel](newMessages[i]);
}
}
}
}
/// <summary>
/// Listen to the channel for subscriptions
/// </summary>
/// <param name="channel"></param>
public void Unsubscribe(string channel)
{
channelMessageHandlers.Remove(channel);
}
}
Unity GUI components
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Chatbox : MonoBehaviour {
private string PlayerName;
private string _playerName;
private string chatText = "";
private List<string> messages = new List<string>();
private Vector2 scrollPosition = Vector2.zero;
/// <summary>
/// Initialize all the player preferences with Guestname<0-999> and the name can be changed by /OnGui
/// </summary>
void Start()
{
PlayerName = PlayerPrefs.GetString("PlayerName", "Guest" + Random.Range(0, 9999));
_playerName = PlayerName;
//subscribe to the specific room
PubNubWrapper.instance.Subscribe("Chatbox", HandleMessage);
}
/// <summary>
/// Handle message sends a string to the list of messages and deletes if over 100
/// </summary>
/// <param name="message"></param>
void HandleMessage(string message)
{
Debug.Log(message);
messages.Add(message);
if (messages.Count > 100)
messages.RemoveAt(0);
//Unity cmlamps the scroll value. Setting it sufficiently high will cause it to scroll to the bottom
scrollPosition.y = messages.Count * 100f;
}
/// <summary>
/// GUI references for changing the player's name
/// </summary>
void OnGUI()
{
_playerName = GUILayout.TextField(_playerName, GUILayout.Width(200f));
if (GUILayout.Button( "Change Name", GUILayout.Width( 200f ) ) )
{
//inform other players that the player has changed name
PubNubWrapper.instance.Publish(PlayerName + " changed their name to " + _playerName, "Chatbox");
//assign the new name
PlayerName = _playerName;
}
scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Width(Screen.width), GUILayout.Height(Screen.height - 75f));
{
// display each message
for (int i = 0; i < messages.Count; i++)
{
GUILayout.Label(messages[i]);
}
}
GUILayout.EndScrollView();
GUILayout.BeginHorizontal(GUILayout.Width(Screen.width));
{
chatText = GUILayout.TextField(chatText, GUILayout.ExpandWidth(true));
if(GUILayout.Button( "Send", GUILayout.Width(100f ) ))
{
//publish the message the player types as:
// [playername] : [message]
if (chatText.StartsWith("/me "))
{
chatText = chatText.Replace("/me", "");
PubNubWrapper.instance.Publish(PlayerName + chatText, "Chatbox");
}
else
{
PubNubWrapper.instance.Publish(PlayerName + ": " + chatText, "Chatbox");
}
// clear the textbox
chatText = "";
}
}
GUILayout.EndHorizontal();
}
/// <summary>
/// Quit the chat box when the player leaves the room and save it for them later
/// </summary>
void OnApplicationQuit()
{
PlayerPrefs.SetString("PlayerName", PlayerName);
}
// Update is called once per frame
void Update () {
}
}
The other thing about this is the webpage will understand the connection, except it won't get the publish and subscribe right. I would like to eventually do more projects so it seems the biggest bottleneck is Unity but I understand I can't do much to change the Asset.
'
I do not own the rights to the code, they are taken from the PubNub website and Unity Multiplayer Games textbook. I simply just made the connection of using a runnable server.

Windows phone 8.1 background task and foreground app communication

I am working on a Windows Phone 8.1 application which registers a background task timer trigger for hourly operation. So essentially, the background task wake up every 60 minutes and does some operation.
My question is that, when the background task is in progress, if the user wakes up the application, is there a way that we can show the user what is happening in the background task process?
I understand that they are two different processes. I am using a Silverlight 8.1 project for the foreground application and a managed windows runtime project for the background task. I am registering the background task using the silverlight application but i am in a dark now thinking about how to create a communication bridge between these two processes.
Any clues ? Is this even possible ?
Here are some ideas (or info) about communication between the app and its background tasks.
You could use the Progress and Completed events of the IBackgroundTaskRegistration object. You can get that object using BackgroundTaskRegistration.AllTasks - this property returns the list of background tasks registered by the app. Each time the app runs, you'll have to subscribe to these events.
From the background task you can set the Progress property of the IBackgroundTaskInstance object to some UInt32 value, and the app will receive the event. Maybe you can encode what you need in that number. For example: 1 means that the task is initializing, 2 - the task is doing WorkA, and so on...
Both processess have access to the same files, so maybe you can use that for something.
Use Mutex to sync the execution of code between the two processes.
That's all I can think of right now. I hope it helps.
P.S. I haven't really tried those events, but they seem like they might be useful.
I have already did some POC on commnication b/w Background Task and the app it self. I was using windows universal app but it will work in silverlight phone app too.
private IBackgroundTaskRegistration timeZoonChangeTask;
public MainPage()
{
this.InitializeComponent();
NavigationHelper nvHelper = new NavigationHelper(this);
IReadOnlyDictionary<Guid, IBackgroundTaskRegistration> allTasks = BackgroundTaskRegistration.AllTasks;
if (allTasks.Count() == 0)
{
lblMessage.Text = "No Task is registered at the moment";
}
else//Task already registered
{
lblMessage.Text = "Timezoon Task is registered";
this.GetTask();
}
}
/// <summary>
/// Time zoon task registration.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void Button_Click(object sender, RoutedEventArgs e)
{
await BackgroundExecutionManager.RequestAccessAsync();
BackgroundTaskBuilder taskBuilder = new BackgroundTaskBuilder();
taskBuilder.Name = "MyBackgroundTask";
SystemTrigger systemTrigger = new SystemTrigger(SystemTriggerType.TimeZoneChange, false);
taskBuilder.SetTrigger(systemTrigger);
taskBuilder.TaskEntryPoint = typeof(MyBackgroundTask.TheTask).FullName;
taskBuilder.Register();
lblMessage.Text = "Timezoon Task is registered";
this.GetTask();
}
/// Get registered task and handel completed and progress changed events.
/// </summary>
private void GetTask()
{
var timeZoonChangeTask = BackgroundTaskRegistration.AllTasks.Values.FirstOrDefault();
timeZoonChangeTask.Completed += timeZoonChangeTask_Completed;
timeZoonChangeTask.Progress += timeZoonChangeTask_Progress;
}
/// <summary>
/// raised when task progress is changed app is active
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
void timeZoonChangeTask_Progress(BackgroundTaskRegistration sender, BackgroundTaskProgressEventArgs args)
{
this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
lblTaskProgress.Text = args.Progress.ToString() + "%";
recProgress.Width = 400 * (double.Parse(args.Progress.ToString()) / 100);
});
//this.Dispatcher.BeginInvoke(() =>
// {
// });
}
/// <summary>
/// Raised when task is completed and app is forground
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
void timeZoonChangeTask_Completed(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args)
{
this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
lblMessage.Text = "Task Excecution is completed";
});
}
and below is the task class
public sealed class TheTask:IBackgroundTask
{
public async void Run(IBackgroundTaskInstance taskInstance)
{
///Get Deferral if we are doing aysnc work. otherwise it will not work.
//Always get deferral it will not harm.
var deferral = taskInstance.GetDeferral();
taskInstance.Canceled += taskInstance_Canceled;
for (uint i = 0; i < 10; i++)
{
taskInstance.Progress = i + 10;
await Task.Delay(2000);
}
//Write last run time somewhere so the gorground app know that at when last time this backgournd app ran.
///Set this progress to show the progesss on the forground app if it is running and you want to show it.
taskInstance.Progress = 0;
deferral.Complete();
}
void taskInstance_Canceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
}
}

Store class instance - Windows store application

I'm a bit new to programing a windows store app.So the question is how can I save an instance of a class in to an xml or binary file.I tried some code but it isn't working.
Hope that some one can steer me in the right direction .
You can serialize your instance by using this code
/// <summary>
/// Deserializes the XML.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="xml">The XML.</param>
/// <returns>The instance</returns>
public static T DeserializeXml<T>(this String xml)
{
var bytes = Encoding.UTF8.GetBytes(xml);
using (var stream = new MemoryStream(bytes))
{
var serializer = new DataContractSerializer(typeof(T));
return (T)serializer.ReadObject(stream);
}
}
/// <summary>
/// Serializes the specified instance.
/// </summary>
/// <param name="instance">The instance.</param>
/// <returns>Xml</returns>
public static String SerializeXml(this Object instance)
{
using (var stream = new MemoryStream())
{
var serializer = new DataContractSerializer(instance.GetType());
serializer.WriteObject(stream, instance);
stream.Position = 0;
using (var reader = new StreamReader(stream))
{
var result = "<?xml version='1.0' encoding='UTF-8' ?>";
result += reader.ReadToEnd();
return result;
}
}
}
Next step is to save the serialized instance text to a file.
var filename = "instance.txt";
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists);
var content = yourInstance.SerializeXml();
await FileIO.WriteTextAsync(file, content, Windows.Storage.Streams.UnicodeEncoding.Utf8);
Now there should be a file in your AppPackage-Local-Folder called instance.txt which contains the current instance serialized to xml.
You can use Windows.Storage to store any file, the usage is like IO operation. MSDN
IsolatedStorage is similar to this for Windows Phone apps.