lunedì 25 luglio 2016

Barbarie nel traffico

New Entries
- In una grande città deserta nel weekend di Ferragosto parcheggiare in divieto di sosta per non fare cinque metri in più
- Città deserta, un solo pedone e una sola auto all'orizzonte. L'auto inchioda per non investire il pedone sulle strisce. Segue discussione che blocca le poche macchine circolanti.

Questa mattina tutte a me:
  1. parcheggiare in doppia fila davanti alla mia macchina
  2. svuotare al semaforo il portacenere dal finestrino
  3. impegnare l'area di intersezione di un incrocio anche quando la circolazione è bloccata (effetto tappo)
  4. parcheggiare in doppia fila all'altezza di un'altra macchina in doppia fila in direzione opposta (effetto imbuto)
  5. procedere ad andatura lentissima al centro della strada e infine passare col giallo quasi rosso
  6. guidare col telefono in mano senza lasciar intendere le traiettorie che si intraprenderanno

domenica 29 maggio 2016

Dettatura in italiano con Cortana

Sebbene quella del riconoscimento vocale sia ormai una tecnologia mainstream, il suo utilizzo è ancora piuttosto scarso a causa di un limite culturale o, più probabilmente, per la mancanza di interfacce vocali ben fatte.
Android e Apple Ios hanno i propri sistemi di dettatura integrati così come Windows, ma fino a Windows 7 l'unico modo per dettare in Italiano con i sistemi operativi Microsoft era installare un software commerciale come Dragon NaturallySpeaking.
Con Cortana e Windows 10 siamo passati alla seconda generazione dei motori di riconoscimento vocale, grazie all'utilizzo di modelli basati sulle reti neurali profonde (DNN).
Microsoft ha reso disponibile il riconoscimento vocale in decine di lingue, ma mancano le applicazioni che lo utilizzano tant'è che a oggi è possibile solamente dettare degli SMS con Windows phone oppure rivolgere delle domande a Cortana. Dettare delle email o un documento in Word è possibile in potenza ma di fatto manca ancora l'integrazione con Cortana.
Eppure le API ci sono. Basta avere Windows 10 e un collegamento a internet perché Cortana trascriva la nostra voce in tempo reale.
Le API di Cortana sono API WinRT, cioè pensate per le App Windows Store ma, esattamente come descritto nel post per le API OCR, è possibile utilizzarle in una normale applicazione desktop.
Qui un semplice progetto WPF che integra le API Windows.Media.SpeechRecognition con cui potrete giudicare l'accuratezza di Cortana.
Richiede Windows 10, l'accesso a Internet e l'input audio microfonico.
Quando terminate di parlare premete il pulsante Stop altrimenti il sistema produrrà un Timeout.
E qui l'esempio ufficiale di Microsoft

Update 23/06/2017: addin Office per la dettatura

martedì 29 marzo 2016

Log Tail in Windows

Domandandomi se ci fosse un comando simile a tail -f in Windows mi sono imbattuto in questo comando PowerShell:

Get-Content myfile.log -Wait

Proprio ora a Build 2016 hanno annunciato una shell bash nativa per Windows 10. Straordinario

lunedì 28 marzo 2016

Come utilizzare le API WinRT di Windows 10 in una applicazione desktop console C#

Sono entusiasta delle possibilità offerte dalle api WinRT di Windows 10 nelle applicazioni UWP, peccato usarle solo in app "sandboxed"
In realtà la maggior parte di queste API si possono utilizzare anche in applicazioni classiche desktop.
Vediamo ad esempio come utilizzare le librerie OCR in un programma a riga di comando che prende in ingresso un file contenente un'immagine e genera un file .txt con il risultato.

Con Visual Studio 2015 genera un nuovo progetto Visual C#->Windows->Classic Desktop->Console Application OCRConsole
  • Con il pulsante destro sul progetto fai Unload Project
  • Con il pulsante destro sul progetto fai Edit OCRConsole.csproj
  • Aggiungi <TargetPlatformVersion>10.0</TargetPlatformVersion> sotto <TargetFrameworkVersion>
  • Con il pulsante destro sul progetto fai Reload Project
  • Add Reference->Browse Windows.winmd da C:\Program Files (x86)\Windows Kits\10\UnionMetadata
  • Add Reference->Browse System.Runtime.WindowsRuntime da C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.WindowsRuntime.dll. Nelle proprietà di System.Runtime.WindowsRuntime setta "Copy Local=False"
  • Se ottieni in compilazione un errore del tipo 'await' requires that the type 'Windows.Foundation.IAsyncOperation' have a suitable GetAwaiter method., verifica che il codice inizi con using System; Verifica anche che nel progetto il percorso System.Runtime.WindowsRuntime.dll sia assoluto

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Globalization;
using Windows.Graphics.Imaging;
using Windows.Media.Ocr;
using Windows.Storage;

namespace OCRConsole
{
    class Program
    {
        static private OcrEngine ocrEngine;
        static private string filePath;

        static async Task OCRAsync()
        {
            // Do any async anything you need here without worry
            // Load image from install folder.
            var file = await StorageFile.GetFileFromPathAsync(filePath);
            using (var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
            {
                // Create image decoder.
                var decoder = await BitmapDecoder.CreateAsync(stream);
                // Load bitmap.
                var bitmap = await decoder.GetSoftwareBitmapAsync();
                // Extract text from image.
                OcrResult result = await ocrEngine.RecognizeAsync(bitmap);
                // Display recognized text.
                File.WriteAllText(Path.ChangeExtension(filePath, "txt"), result.Text, Encoding.Default);
               
            }
        }

        static void Main(string[] args)
        {
            if (args.Length != 1)
            {
                Console.WriteLine("Usage: OCRConsole <filepath>");
                return;
            }

            filePath = args[0];
            if (!File.Exists(filePath))
            {
                Console.WriteLine("The file {0} doesn't exist", filePath);
                return;
            }
           
            // Init OCR engine with Italian language.
            ocrEngine = OcrEngine.TryCreateFromLanguage(new Language("it"));
            OCRAsync().GetAwaiter().GetResult();
           
        }
    }
}

Una volta per ottenere questo risultato ci voleva un SDK apposito, tonnellate di codice C++ e qualche giorno di sviluppo.