Thursday, April 27, 2017

Call java program from Node.js application

Leave a Comment

From what I read, there are a couple of ways to run java files in a node.js application. One way is to spawn a child process: (the java code is packaged with dependencies in an executable jar.)

var exec = require('child_process').exec, child;     child = exec('java -jar file.jar arg1 arg2',       function (error, stdout, stderr){         console.log('stdout: ' + stdout);         console.log('stderr: ' + stderr);         if(error !== null){           console.log('exec error: ' + error);         }     }); 

The other way is to use the java - npm module (link), a wrapper over JNI (this will let me create objects, set and get attributes, run methods).

In a production environment, when I want my node.js (Express) server to call a java program (it just saves an image to the local directory), please advise me on which would be the better way to accomplish this (in terms of best practices). Also, there is a long list of arguments that I need to pass to the main class and doing that on the command line is a bit of a struggle. Should I make the java program read from an input file instead?

4 Answers

Answers 1

1) If you use exec, you will run an entire program, whereas if you use a JNI interface, you'll be able to directly interact with the libraries and classes in the jar and do things like call a single function or create an instance of a class. However, if you don't need anything like that, I think using exec is far simpler and will also run faster. Sounds like you just want to run the Java application as a standalone process, and just log whether the application finished successfully or with errors. I'd say it's probably better to just use exec for that. Executing a child process this way is also far better for debugging, debugging JNI errors can be very difficult sometimes.

2) As for whether or not to read arguments from a file, yes, it's usually better to read from some sort of file as opposed to passing in arguments directly. It's less prone to human error (ie. typing in arguments every time), and far more configurable. If someone like a QA engineer only needs to edit a config file to swap out options, they don't need to understand your entire codebase to test it. Personally I use config files for every Java program I write.

Answers 2

You can use deployment toolkit and run the jar through jnlp. https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/deployment_toolkit.html Advantage of running jars through jnlp is the ability to pass parameters from javascript to your jar. In this way you can dynamically customize your java program.

Answers 3

For this kind of problem you'd want to approach it in the following way:

  • Is there a decent way to run processes with arguments in my language/framework
  • Is there a decent way to deal with the programs output?

From experience, a decent way to deal with arguments in a process is to pass them as an (string) array. This is advantageous in that you do not have to resort to unnecessary string interpolation and manipulation. It is also more readable too which is a plus in this problem setting.

A decent way to deal with output is to use a listener/event based model. This way, you respond appropriately to the events instead of having if blocks for stderr and stdout. Again, this makes things readable and let's you handle output in a more maintainable manner.

If you go a bit further into this, you will also have to solve a problem of how to inject environment variables into your target program. As an example, you might want to run the java with a debugger or with less memory in the future, so your solution would also need to cater for this.

This is just one way of solving this kind of problem. If node is your platform, then have a look at Child Process which supports all of these techniques.

Answers 4

Try this into nodejs file:
https://www.npmjs.com/package/java
Or this into html response file:
<object width="400" height="400" data="helloworld.swf"></object>

Read More

Remove glare from photo opencv

Leave a Comment

So, im using opencv to capture a document, scan it and crop it. When there is no lighting in the room, it works perfectly. When there is some light in the room, and there is a glare on the table and the document is near it, it also grabs the glare as part of the rectangle.

How can one remove the glare from the photo?

Here is the code im using to get the image I want:

 Mat &image = *(Mat *) matAddrRgba;     Rect bounding_rect;      Mat thr(image.rows, image.cols, CV_8UC1);     cvtColor(image, thr, CV_BGR2GRAY); //Convert to gray     threshold(thr, thr, 150, 255, THRESH_BINARY + THRESH_OTSU); //Threshold the gray      vector<vector<Point> > contours; // Vector for storing contour     vector<Vec4i> hierarchy;     findContours(thr, contours, hierarchy, CV_RETR_CCOMP,                  CV_CHAIN_APPROX_SIMPLE); // Find the contours in the image     sort(contours.begin(), contours.end(),          compareContourAreas);            //Store the index of largest contour     bounding_rect = boundingRect(contours[0]);      rectangle(image, bounding_rect, Scalar(250, 250, 250), 5); 

Here is a photo of the glare im talking about:

enter image description here

The things I have found are to use inRange, find the apropriate scalar for color and us inpaint to remove light. Here is a code snippet of that, but it always crashes saying it needs 8bit image with chanels.

Mat &image = *(Mat *) matAddrRgba;      Mat hsv, newImage, inpaintMask;     cv::Mat lower_red_hue_range;     inpaintMask = Mat::zeros(image.size(), CV_8U);     cvtColor(image, hsv, COLOR_BGR2HSV);     cv::inRange(hsv, cv::Scalar(0, 0, 215, 0), cv::Scalar(180, 255, 255, 0),                 lower_red_hue_range);     image = lower_red_hue_range;      inpaint(image, lower_red_hue_range, newImage, 3, INPAINT_TELEA); 

2 Answers

Answers 1

I have dealt with this problem before, and change in lighting is always a problem in Computer Vision for detection and description of images. I actually trained a classifier, for HSV color spaces instead of RGB/BGR, which was mapping the image with changing incident light to the one which doesn't have the sudden brightness/dark patches (this would be the label). This worked for me quite well, however, the images were always of the same background (I don't know if you also have this).

Of course, machine learning can solve the problem but it might be an overkill. While I was doing the above mentioned, I came across CLAHE which worked pretty well with for local contrast enhancement. I suggest you to try this before detecting contours. Additionally, you might want to work on a different color space, such as HSV/Lab/Luv instead of RGB/BGR for this purpose. You can apply CLAHE separately to each channel and then merge them.

Let me know if you need some other information. I implemented this with your image in python, it works pretty nicely, but I would leave the coding to you. I might update the results I got after a couple of days (hoping that you get them first ;) ). Hope it helps.

Answers 2

hey glare is kind of noise in the image so try this to remove noise from color images. ``

import numpy as np import cv2 from matplotlib import pyplot as plt img = cv2.imread('die.png') dst = cv2.fastNlMeansDenoisingColored(img,None,10,10,7,21) plt.subplot(121),plt.imshow(img) plt.subplot(122),plt.imshow(dst) plt.show() 

the result is

enter image description here

Read More

Possible to overwrite existing push notification on iOS

Leave a Comment

In Android it is possible to overwrite an existing push notification if you keep using the same notification id.

Is the same possible for iOS in any way?

It seems hard to find any information about replacing an push notification, because a lot of answers are using silent push notifications and remove them manually.

I use Cordova so I have limited options for background processes when receiving push notifications.

On iOS I cannot run code to manually remove any push notifications when the app is in the background.

1 Answers

Answers 1

No, in iOS you can not overwrite already scheduled remote / local notification.

You have to schedule another push notification.

By maintaining some flag or checking on key / value. You have to remove previous notification while reviving new notification.

Hope this helps.

Updated

As an alternate, once you receive push notification, on based of information you received in push notification payload.

You can schedule local notification.

import UIKit import PushKit  @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate,PKPushRegistryDelegate {  var window: UIWindow? let notificationObject = UILocalNotification()  func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {       return true }  func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {        notificationObject.fireDate = NSDate(timeIntervalSinceNow: 1)     notificationObject.alertBody =  "Title"     notificationObject.alertAction = "Open"     notificationObject.soundName = "SoundFile.mp3"     notificationObject.category = ""     notificationObject.userInfo = "As per payload you receive"      UIApplication.sharedApplication().scheduleLocalNotification(notificationObjectCall)   } 

As you can see in above code, local notification object is declared globally. So that object will get overwrite again and again whenever you receive payload.

For remote notification, you can not make object and overwrite it.

I am not much aware of cordova, but in native iOS, this way, you can do overwrite using local notification.

Hope you understand what technique is been used and help you figure out solution.

Read More

Jquery Datepicker select multiple date ranges in one calender

Leave a Comment

My requirement is to allow user to select multiple date ranges in a single calendar, also previous date selections should not be allowed to change. How is this possible? Below is the code and link to fiddle

HTML

<p>from</p> <input type="text" class="spromotion-input-inbody spromotion-input-datepick" id="sproid-bookingcondition-datefrom"> <p>to</p> <input type="text" class="spromotion-input-inbody spromotion-input-datepick" id="sproid-bookingcondition-dateto"> 

SCRIPT

$( function() {     var dateFormat = "mm/dd/yy",       from = $( "#sproid-bookingcondition-datefrom" )         .datepicker({           defaultDate: "+1w",           changeMonth: true,           numberOfMonths: 1         })         .on( "change", function() {           to.datepicker( "option", "minDate", getDate( this ) );         }),       to = $( "#sproid-bookingcondition-dateto" ).datepicker({         defaultDate: "+1w",         changeMonth: true,         numberOfMonths: 1       })       .on( "change", function() {         from.datepicker( "option", "maxDate", getDate( this ) );       });      function getDate( element ) {       var date;       try {         date = $.datepicker.parseDate( dateFormat, element.value );       } catch( error ) {         date = null;       }        return date;     }   } ); 

5 Answers

Answers 1

Please check this might solve your issue.

$(function() {      $('input[name="daterange"]').daterangepicker();      $('input[name="daterange"]').change(function(){        $(this).val();        console.log($(this).val());      });  });
<html>  <head>  <!-- Include Required Prerequisites -->  <script type="text/javascript" src="//cdn.jsdelivr.net/jquery/1/jquery.min.js"></script>  <script type="text/javascript" src="//cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>  <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/bootstrap/3/css/bootstrap.css" />     <!-- Include Date Range Picker -->  <script type="text/javascript" src="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.js"></script>  <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.css" />  </head>  <body>    <input class="pull-right" type="text" name="daterange" value="01/15/2020 - 02/15/2010">  </body>  </html>

Answers 2

I think this Multi datepicker will help you to solve your problem.

$('#mdp-demo').multiDatesPicker();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>  <link href="https://cdn.rawgit.com/dubrox/Multiple-Dates-Picker-for-jQuery-UI/master/jquery-ui.multidatespicker.css" rel="stylesheet"/>  <link href="https://code.jquery.com/ui/1.12.1/themes/pepper-grinder/jquery-ui.css" rel="stylesheet"/>  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>  <script src="https://cdn.rawgit.com/dubrox/Multiple-Dates-Picker-for-jQuery-UI/master/jquery-ui.multidatespicker.js"></script>  <div id="mdp-demo"></div>

Answers 3

Unfortunately this is not something the datepicker plugin is able to do out of the box. You will need some custom JavaScript to enable this.

I found a way which gets close to what you want using the onSelect and beforeShowDay events. It maintains its own array of selected dates, so unfortunately doesn't integrate with a textbox showing the current date, etc. I'm just using it as an inline control, and I can then query the array for the currently selected dates.

The only thing you would need to alter about this code is grouping every two dates into ranges, but there are multiple ways to do that depending on your desired UX. Personally, I would just group every two dates as a range in the order the user selects. Then if they remove a date from any range, the entire range is removed (that is not coded here, you will need to add that).

Here is my code:

<script> // Maintain array of dates var dates = new Array();  function addDate(date) {     if (jQuery.inArray(date, dates) < 0)          dates.push(date); }  function removeDate(index) {     dates.splice(index, 1); }  // Adds a date if we don't have it yet, else remove it function addOrRemoveDate(date) {     var index = jQuery.inArray(date, dates);     if (index >= 0)          removeDate(index);     else          addDate(date);     }  // Takes a 1-digit number and inserts a zero before it function padNumber(number) { var ret = new String(number); if (ret.length == 1)      ret = "0" + ret;     return ret; }  jQuery(function () {     jQuery("#datepicker").datepicker({         onSelect: function (dateText, inst) {             addOrRemoveDate(dateText);         },         beforeShowDay: function (date) {             var year = date.getFullYear();             // months and days are inserted into the array in the form, e.g "01/01/2009", but here the format is "1/1/2009"             var month = padNumber(date.getMonth() + 1);             var day = padNumber(date.getDate());             // This depends on the datepicker's date format             var dateString = month + "/" + day + "/" + year;              var gotDate = jQuery.inArray(dateString, dates);             if (gotDate >= 0) {                 // Enable date so it can be deselected. Set style to be highlighted                 return [true, "ui-state-highlight"];             }             // Dates not in the array are left enabled, but with no extra style             return [true, ""];         }     }); }); </script> 

And here is a fiddle: http://jsfiddle.net/gydL0epa/

Answers 4

As others already suggested, MultiDatesPicker comes close to what your need. It already allows single range selection, so you could fork that plugin and edit/improve it to allow multiple ranges selection.

A quick and dirty solution would be to comment out the line where the array of selected dates gets reset.

Answers 5

try this

<!DOCTYPE html> <html> <head>     <title></title>     <meta charset="utf-8" />     <script src="Scripts/jquery-1.11.1.js"></script>     <script src="Scripts/jquery-ui-1.11.1.js"></script>     <script src="Scripts/jquery-ui.multidatespicker.js"></script>     <link href="css/jquery-ui.css" rel="stylesheet" />     <link href="css/jquery-ui.structure.css" rel="stylesheet" />     <link href="css/jquery-ui.theme.css" rel="stylesheet" />     <link href="css/pepper-ginder-custom.css" rel="stylesheet" />     <link href="css/prettify.css" rel="stylesheet" /> </head>  <body>     <input type="text" id="fromDate" />     <script>         $(function () {             $('#fromDate').multiDatesPicker();         });     </script> </body> </html> 

you can download the js file from the link https://sourceforge.net/projects/multidatespickr/

Read More

Can tesseract be trained for non-font symbols?

Leave a Comment

I'm curious about how I may be able to more reliably recognise the value and the suit of playing card images. Here are two examples:

enter image description here enter image description here

There may be some noise in the images, but I have a large dataset of images that I could use for training (roughly 10k pngs, including all values & suits).

I can reliably recognise images that I've manually classified, if I have a known exact-match using a hashing method. But since I'm hashing images based on their content, then the slightest noise changes the hash and results in an image being treated as unknown. This is what I'm looking to reliably address with further automation.

I've been reviewing the 3.05 documentation on training tesseract: https://github.com/tesseract-ocr/tesseract/wiki/Training-Tesseract#automated-method

Can tesseract only be trained with images found in fonts? Or could I use it to recognise the suits for these cards?

I was hoping that I could say that all images in this folder correspond to 4c (e.g. the example images above), and that tesseract would see the similarity in any future instances of that image (regardless of noise) and also read that as 4c. Is this possible? Does anyone here have experience with this?

1 Answers

Answers 1

This has been my non-tesseract solution to this, until someone proves there's a better way. I've setup:

Getting these to running was the hardest part. Next, I used my dataset to train a new caffe network. I prepared my dataset into a single depth folder structure:

./card ./card/2c ./card/2d ./card/2h ./card/2s ./card/3c ./card/3d ./card/3h ./card/3s ./card/4c ./card/4d ./card/4h ./card/4s ./card/5c ./card/5d ./card/5h ./card/5s ./card/6c ./card/6d ./card/6h ./card/6s ./card/7c ./card/7d ./card/7h ./card/7s ./card/8c ./card/8d ./card/8h ./card/8s ./card/9c ./card/9d ./card/9h ./card/9s ./card/_noise ./card/_table ./card/Ac ./card/Ad ./card/Ah ./card/As ./card/Jc ./card/Jd ./card/Jh ./card/Js ./card/Kc ./card/Kd ./card/Kh ./card/Ks ./card/Qc ./card/Qd ./card/Qh ./card/Qs ./card/Tc ./card/Td ./card/Th ./card/Ts 

Within Digits, I chose:

  1. Datasets tab
  2. New Dataset Images
  3. Classification
  4. I pointed it to my card folder, e.g: /path/to/card
  5. I set the validation % to 13.0%, based on the discussion here: http://stackoverflow.com/a/13612921/880837
  6. After creating the dataset, I opened the models tab
  7. Chose my new dataset.
  8. Chose the GoogLeNet under Standard Networks, and left it to train.

I did this several times, each time I had new images in the dataset. Each learning session took 6-10 hours, but at this stage I can use my caffemodel to programmatically estimate what each image is expected to be, using this logic: https://github.com/BVLC/caffe/blob/master/examples/cpp_classification/classification.cpp

The results are either a card (2c, 7h, etc), noise, or table. Any estimates with an accuracy bigger than 90% are most likely correct. The latest run correctly recognised 300 out of 400 images, with only 3 mistakes. I'm adding new images to the dataset and retraining the existing model, further tuning the result accuracy. Hope this is valuable to others!

While I wanted the high level steps here, this was all done with large thanks to David Humphrey and his github post, I really recommend reading it and trying it out if you're interested in learning more: https://github.com/humphd/have-fun-with-machine-learning

Read More

Wednesday, April 26, 2017

How to play .mts file in iOS

Leave a Comment

Currently im working with a wifi-camera device, which is able to send only videos in .mts format. As i have investigated in google, it leads to conclusion that it is not possible to play the video in iPhone or may be using Objective C.

Now my problem what is,

There is still many paid applications that allows us to play .mts files

PlayerXtreme is able to run files in almost any video format. It has currently the following formats covered:  3gp, asf, avi, divx, dv, dat, flv, gxf, m2p, m2ts, m2v, m4v, mkv, moov, mov, mp4, mpeg, mpeg1, mpeg2, mpeg4, mpg, mpv, mt2s, mts, mxf, ogm, ogv, ps, qt, rm, rmvb, ts, vob, webm, wm, wmv 

See the application: iTunes app

Player i m curently trying is AVPlayer lib

How can i start the coding to get this done in my app also?

Currently I'm trying solve by adding some python scripts to my project as a build.. and calling the same for converting to mp4 format.. anyone worked on py-ObjC Together in XCode pls give some idea..

1 Answers

Answers 1

MTS is a container format. You need to know what the video and audio codecs are, and see whether VideoToolbox and AudioToolbox (the underlying frameworks of AVPlayer) support those codecs.

Assuming H264 for video and AAC or AC3 for audio, libavcodec (part of ffmpeg) supports the MTS container. You can use that to demux the video and audio streams, and then use VTDecompressionSession and AudioQueueNewOutput (I think, I haven’t used that API in a while).

Read More

Node.js BinaryServer: Send a message to the client on stream end?

Leave a Comment

I'm using a node.js BinaryServer for streaming binary data and I want a callback event from the server, after the client calls for the .Stream.end() function.

I can't seem to understand - How can I send a message or some kind of notification when the node.js server actually closes the stream connection ?

Node JS:

server.on('connection', function(client) {      client.on('stream', function (stream, meta) {          stream.on('end', function () {             fileWriter.end();             // <--- I want to send an event to the client here         });     });  }); 

client JS:

client = new BinaryClient(nodeURL); window.Stream = client.createStream({ metaData }); .... window.Stream.end(); //  <--- I want to recieve the callback message 

1 Answers

Answers 1

On the server side, you can send streams to the client with .send. You can send a variety of data types, but a simple string will probably suffice in this case.

On the client side you can also listen to the 'stream' event to receive data back from the server.

Node JS:

server.on('connection', function(client) {     client.on('stream', function (stream, meta) {         stream.on('end', function () {             fileWriter.end();             client.send('finished');         });     });     }); 

client JS:

client = new BinaryClient(nodeURL); client.on('stream', data => {     console.log(data); // do something with data }); window.Stream = client.createStream({ metaData }); .... window.Stream.end(); 
Read More