Google OCR language hints - google-cloud-platform

It says on the documentation page here: https://cloud.google.com/vision/docs/ocr that you can specify language hints to help OCR more accurately detect text in the image. Does anyone know where I would specify a language hint in my code? I am programming it using a .net console application.
using Google.Cloud.Vision.V1;
using System;
namespace GoogleCloudSamples
{
public class QuickStart
{
public static void Main(string[] args)
{
// Instantiates a client
var client = ImageAnnotatorClient.Create();
// Load the image file into memory
var image = Image.FromFile("wakeupcat.jpg");
// Performs label detection on the image file
var response = client.DetectLabels(image);
foreach (var annotation in response)
{
if (annotation.Description != null)
Console.WriteLine(annotation.Description);
}
}
}
}
I can't seem to access the language hints property of the ImageContext class because it is read only. Is there a way to create an ImageContext where I can specify the language hints?

You can create ImageContext object & set it in your AnnotateImageRequest using:
// Build ImageContext object
ImageContext imageContext = ImageContext.newBuilder().addLanguageHints("en").build();
// Set it to AnnotateImageRequest
AnnotateImageRequest request = AnnotateImageRequest.newBuilder().addFeatures(feat).setImage(img).setImageContext(imageContext).build();

I had same problem and solved it. LanguageHints is List. You can add language. Of course you can add multiple languages also.
ImageContext imageContext = new ImageContext();
imageContext.LanguageHints.Add("en");
imageContext.LanguageHints.Add("ko");

Related

M2Doc error <---Couldn't find the 'getText(EClassifier=Model)' service

I was using m2doc programmatically, and this is my code.
final URI templateURI = URI.createFileURI(templateName+"."+M2DocUtils.DOCX_EXTENSION_FILE);
final URI modelURI = URI.createFileURI(modelName);
// can be empty, if you are using a Generation use GenconfUtils.getOptions(generation)
final Map<String, String> options = new HashMap<>();
List<Exception> exceptions = new ArrayList<>();
final ResourceSet resourceSetForModels = M2DocUtils.createResourceSetForModels(exceptions , "key", new ResourceSetImpl(), options);
//resourceSetForModels.getResource(modelURI, true);
final Resource r = resourceSetForModels.getResource(modelURI, true);
System.out.println(r.getContents());
final EObject value = r.getContents().get(0);
// if you are using a Generation, use GenconfUtils.getQueryEnvironment(resourceSetForModels, generation)
final IQueryEnvironment queryEnvironment = M2DocUtils.getQueryEnvironment(resourceSetForModels, templateURI, options); // delegate to IServicesConfigurator
final IClassProvider classProvider = new ClassProvider(this.getClass().getClassLoader()); // use M2DocPlugin.getClassProvider() when running inside Eclipse
final Monitor monitor = new BasicMonitor.Printing(System.out);
try (DocumentTemplate template = M2DocUtils.parse(resourceSetForModels.getURIConverter(), templateURI, queryEnvironment, classProvider, monitor)) {
// validate
final ValidationMessageLevel validationLevel = M2DocUtils.validate(template, queryEnvironment, monitor);
if (validationLevel != ValidationMessageLevel.OK) {
final URI validationResulURI = URI.createFileURI(templateName+"-validation."+M2DocUtils.DOCX_EXTENSION_FILE); // some place to serialize the result of the validation
M2DocUtils.serializeValidatedDocumentTemplate(resourceSetForModels.getURIConverter(), template, validationResulURI);}
//generate
final Map<String, Object> variables = new HashMap<>(); // your variables and values
variables.put("self", value);
final URI outputURI = URI.createFileURI(templateName+"-result."+M2DocUtils.DOCX_EXTENSION_FILE); // some place to serialize the result of the generation
M2DocUtils.generate(template, queryEnvironment, variables, resourceSetForModels, outputURI, monitor);
}finally {
M2DocUtils.cleanResourceSetForModels("key", resourceSetForModels);
}
And when I ran the program, the validation file was created, and it shows lots of errors. The errors were like this: <---Couldn't find the 'getText(EClassifier=Model)' service. They appeared everywhere I used the service getText().
When I use the same template and the same uml file to generate document by using the m2doc plugin in eclipse, it went alright.
I wonder if my query environment setting was wrong.
Thank you if you can help me.
M2DocUtils.parse() initialize the IQueryEnvironment with services and nsURIs imported in the template. So you should not need to add anything.
If you are running inside Eclipse you should use:
final IClassProvider classProvider = M2DocPlugin.getClassProvider()
It should help loading your service Class (it use OSGi to load classes from bundles).
You can also check if any TemplateValidationMessage are present with more details:
DocumentTemplate.getBody().getValidationMessages()
At this point either the UML metamodel is not registered or it's your service Class (more likely).
You can register the UML EPackage and see if it helps:
queryEnvironment.registerEPackage(UMLPackage.eINSTANCE)
You can also try to register your service class:
final Set<IService> s = ServiceUtils.getServices(queryEnvironment, SomeServiceClass.class);
ServiceUtils.registerServices(queryEnvironment, s);

How to unit test a single conversational statement

i am working with bots and the Microsoft Bot Framework.
I used the DispatchBot template to generate my bot. (https://learn.microsoft.com/de-de/azure/bot-service/bot-builder-tutorial-dispatch?view=azure-bot-service-4.0&tabs=cs)
For conversational testing, i want to create unit tests. Therefore i used this documentation to gather some informations (https://learn.microsoft.com/de-de/azure/bot-service/unit-test-bots?view=azure-bot-service-4.0&tabs=csharp)
The thing is that i dont want to test dialogs, but a single statement (a question and the right answer)
How can i implement this?
Here you can see the Start of my Dispatchbot.cs file where the magic happens (search of the correct Knowledge Base etc.)
Here's a link to how we create tests for CoreBot. The part you're most likely interested in is testing things under the /Bots directory. Based off of the test code you can find there, you likely want something like:
using System;
using System.Threading;
using System.Threading.Tasks;
using CoreBot.Tests.Common;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Adapters;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.BotBuilderSamples.Bots;
using Microsoft.Extensions.Logging;
using Moq;
using Xunit;
namespace KJCBOT_Tests
{
public class BotTests
{
[Fact]
public async Task TestResponseToQuesion()
{
// Note: this test requires that SaveChangesAsync is made virtual in order to be able to create a mock.
var memoryStorage = new MemoryStorage();
var mockConversationState = new Mock<ConversationState>(memoryStorage)
{
CallBase = true,
};
var mockUserState = new Mock<UserState>(memoryStorage)
{
CallBase = true,
};
// You need to mock a dialog because most bots require a Dialog to instantiate it.
// If yours doesn't you can likely skip this
var mockRootDialog = SimpleMockFactory.CreateMockDialog<Dialog>(null, "mockRootDialog");
var mockLogger = new Mock<ILogger<DispatchBot<Dialog>>>();
// Act
var sut = new DispatchBot<Dialog>(mockConversationState.Object, mockUserState.Object, mockRootDialog.Object, mockLogger.Object);
var testAdapter = new TestAdapter();
var testFlow = new TestFlow(testAdapter, sut);
await testFlow
.Send("<Whatever you want to send>")
.AssertReply("<Whatever you expect the reply to be")
.StartTestAsync();
}
}
}

Autoroute Bulk operations in Orchard

If you customize an autoroute part you have the option to recreate the url on each save.
The help text under this option says:
"Automatically regenerate when editing content
This option will cause the Url to automatically be regenerated when you edit existing content and publish it again, otherwise it will always keep the old route, or you have to perform bulk update in the Autoroute admin."
I have digged all around but I cannot find anywhere an "Autoroute admin".
Is it really there?
It was a proposed feature never implemented?
Any idea to do a bulk update even without an Admin page?
Thanks
EDIT after #joshb suggestion...
I have tried to implement a bulk operation in my controller.
var MyContents = _contentManager.Query<MyContentPart, MyContentPartRecord>().List().ToList();
foreach (var MyContent in MyContents) {
var autoroutePart = recipe.ContentItem.As<AutoroutePart>();
autoroutePart.UseCustomPattern = false;
autoroutePart.DisplayAlias = _autorouteService.GenerateAlias(autoroutePart);
_contentManager.Publish(autoroutePart.ContentItem);
}
In this way it recreates all aliases for the types that contain the given part MyContentPart.
With some more work this code can be encapsulated in a command or in a new tab in Alias UI.
After finished the current project I'm doing I will try that...
You could create a module and implement a command that does a bulk update. Shouldn't be too much work if you're comfortable creating modules. You'll need to implement DefaultOrchardCommandHandler and inject IContentManager to get all the parts you're interested in.
Enable Alias UI in the modules section will give you the admin section for managing routes, however I'm not sure what kind of bulk updates it offers
Publishing the ContentItem will do nothing if it is already Published (as it was in my case).
Instead, one could call the PublishAlias method on the AutorouteService. I ended up with a Controller, something like this:
using Orchard;
using Orchard.Autoroute.Models;
using Orchard.Autoroute.Services;
using Orchard.ContentManagement;
using Orchard.Localization;
using Orchard.Security;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
namespace MyNamespace.MyModule.Controllers {
public class AutorouteBulkUpdateController : Controller {
private readonly IOrchardServices _orchardServices;
private readonly IAutorouteService _autorouteService;
private Localizer T { get; set; }
public AutorouteBulkUpdateController(IOrchardServices orchardServices, IAutorouteService autorouteService) {
_orchardServices = orchardServices;
_autorouteService = autorouteService;
T = NullLocalizer.Instance;
}
public ActionResult Index() {
if (!_orchardServices.Authorizer.Authorize(StandardPermissions.SiteOwner, T("Not authorized to manage settings"))) {
return new HttpUnauthorizedResult();
}
int count = 0;
IEnumerable<AutoroutePart> contents;
do {
//contents = _orchardServices.ContentManager.Query<AutoroutePart>(VersionOptions.Latest, new string[] { "Page" }).Slice(count * 100, 100).ToList();
contents = _orchardServices.ContentManager.Query<AutoroutePart>(VersionOptions.Latest).Slice(count * 100, 100).ToList();
foreach (var autoroutePart in contents) {
var alias = _autorouteService.GenerateAlias(autoroutePart);
if (autoroutePart.DisplayAlias != alias) {
autoroutePart.UseCustomPattern = false;
autoroutePart.DisplayAlias = alias;
_autorouteService.PublishAlias(autoroutePart);
}
}
_orchardServices.TransactionManager.RequireNew();
_orchardServices.ContentManager.Clear();
count += 1;
} while (contents.Any());
return null;
}
}
}

How to generate media item link with id instead of path in Sitecore

Anyone knows how to generate links in sitecore with ID instead of item path?
If you use GetMediaUrl method from the API, I can get this URL:
/~/media/Images/Archive/content/News and Events/News_and_Events_Level2/20070419162739/iwhiz3.jpg
The problem with this approach is that if someone changes the media item name, removes it somewhere or deletes it, the above link will break.
I notice if I insert a media link from rich text editor, I get the link as below:
/~/media/14BDED00E4D64DFD8F74019AED4D74EB.ashx
The second link is better because it's using the item id, so if the actual media item is renamed, removed, or deleted, all related links will be updated too. On top of that, when Sitecore renders the page, it will actually convert the above link and display the item path so it's readable.
I'm using Sitecore 6.5 and currently doing content migration so I need to make sure all internal links are updated properly.
May I know if there is a method to generate the second link by using sitecore API?
Thanks!
The GetMediaItemUrl extension method seems to give you what you want.
public static class ItemExtensions
{
public static string GetMediaItemUrl(this Item item)
{
var mediaUrlOptions = new MediaUrlOptions() { UseItemPath = false, AbsolutePath = true };
return Sitecore.Resources.Media.MediaManager.GetMediaUrl(item, mediaUrlOptions);
}
}
[TestFixture]
public class when_using_items_extensions
{
[Test]
public void a_url_based_on_media_item_id_can_be_generated()
{
// Arrange
Database db = global::Sitecore.Configuration.Factory.GetDatabase("master");
Item item = db.GetItem("/sitecore/media library/Images/MyImage");
// Act
var mediaUrl = item.GetMediaItemUrl();
// Assert
Assert.That(mediaUrl, Is.EqualTo("/~/media/17A1341ABEEC46788F2159843DCEAB03.ashx"));
}
}
These are called dynamic links and you can normally generate them using the LinkManager e.g:
Sitecore.Links.LinkManager.GetDynamicUrl(item)
.. but I'm not sure of the method to do this with Media links (there probably is one but I cant seem to find it and its not on MediaManager) but the basic syntax is:
"/~/media/" + item.ID.ToShortID() + ".ashx"
If you always want to use ID's instead of paths, you can change this setting in webconfig to false (like this):
<setting name="Media.UseItemPaths" value="false"/>`
Here is what the webconfig describes about it:
MEDIA - USE ITEM PATHS FOR URLS
This setting controls if item paths are used for constructing media URLs.
If false, short ids will be used.
Default value: true
Then you can use the default implementation (without additional parameters):
Sitecore.Resources.Media.MediaManager.GetMediaUrl(item);
This is what I use:
var imgField = ((Sitecore.Data.Fields.ImageField)currentItem.Fields["Icon"]);
MediaUrlOptions opt = new MediaUrlOptions();
opt.AlwaysIncludeServerUrl = true;
// Absolute Path works as well. So either use AbsolutePath or AlwaysIncludeServerUrl
opt.AbsolutePath = true;
string mediaUrl = MediaManager.GetMediaUrl(imgField.MediaItem, opt);

Parsing XML webservice and storing the data for presentation on a windows phone 7 device

I'm working on an app that requires extracting data from an xml web service, then I want to store that data (images+titles+datetime ...) to display it on my app then select an item and navigate to another page that displays more info about this item.
Is there a detailed tutorial that explains the parsing and storing process clearly (with the threads) because I'm gonna need it a lot for my app.Thanks!
I usually use this method, but didn't always get me what i want:
var doc = XDocument.Load(new StringReader(e.Result));
var items = from c in doc.Descendants("item")
select new RSSitem()
{
Title = c.Element("title").Value,
Photo = c.Element("img").Attribute("src").Value,
Description = c.Element("description").Value,
Link = c.Element("link").Value,
};
ListBoxNews.ItemsSource = items;
Sounds like you are in over your head (based on the vague nature of your question). So I'm offering my advise to get up to speed, so you can get started and ask a question that we can help give a definitive answer to.
With WP7 and .NET you shouldn't really have to do much manual parsing of Web Services. You should be able to add a Service Reference and generate a proxy which will handle this for you. This will also generate business objects for the data returned by your service.
Once you have that done, you can look into Windows Phone Navigation which should help you transition between pages in your application.
To consume web services:
String baseUri = “your service URI";
WebClient wc = new WebClient();
public MainPage()
{
InitializeComponent();
wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_downloadstringcompleted);
// event handler that will handle the ‘downloadstringsompleted’ event
wc.DownloadStringAsync(new Uri(baseUri));
// this method will download your string URI asynchronously
}
void wc_downloadstringcompleted(Object sender, DownloadStringCompletedEventArgs e)
{
// method will get fired after URI download completes
// writes your every code here
}
To parse the data:
using (XmlReader reader = XmlReader.Create(new StringReader(xmlString)))
{
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
break;
case XmlNodeType.Text:
break;
case XmlNodeType.EndElement:
break;
}
}
}
}
To store in isolated storage: http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstoragesettings%28v=vs.95%29.aspx
For navigation:
NavigationService.Navigate(new Uri("/SecondPage.xaml?msg=" + navigationstring, UriKind.Relative));