Upgrading to latest version of Boofcv - java

I'm currently running an old version (0.17) of Boofcv and want to upgrade. The documentation (https://boofcv.org/index.php?title=Download ) is confusing:
The easiest way to use boofcv is to reference its jars on Maven
Central. See below for Maven and Gradle code. BoofCV is broken up into
many modules. To make it easier to use BoofCV all of its core
functionality can be referenced using the 'all' module. Individual
modules in "integration" still must be referenced individually.
Artifact List
boofcv-core : All the core functionality of BoofCV
boofcv-all : All the core and integration packages in BoofCV. YOU PROBABLY WANT CORE AND NOT THIS
This is self-contradictory - do we use "all" or "core"?
When I introduce 0.32 version of boofcv-core I get many unresolved references, such as
Description Resource Path Location Type
ImageFloat32 cannot be resolved to a type BoofCVTest.java
Three parts of my question:
Have the fundamental types for images been renamed?
How will legacy code need editing?
What is the default set of libraries in Maven?

There's been a lot of refactoring since 0.17 because of how verbose things were getting and to simplify the API. For example, ImageFloat32 is now GrayF32. The easiest way to figure out all the changes is to look at the relevant example code.
For modules, start with boofcv-core. Then add modules listed in integration as needed. For example if you need android support add boofcv-android. If you include boofcv-all you will have a lot of stuff you probably don't need, like Kinect support.

To help others who are upgrading, here is an example of the changes I have made to upgrade to current Boofcv. They don't seem to be too difficult ; I have simply used
s/ImageUInt/GrayU/g
and similar for other types. So far I have only found one method that needs changing (VisualizeBinaryData.renderBinary).
/** thresholds an image
* uses BoofCV 0.32 or later
* NOT YET TESTED
*
* #param image
* #param threshold
* #return thresholded BufferedImage
*/
/* WAS Boofcv 0.17
public static BufferedImage boofCVBinarization(BufferedImage image, int threshold) {
ImageUInt8 input = ConvertBufferedImage.convertFrom(image,(ImageUInt8)null);
ImageUInt8 binary = new ImageUInt8(input.getWidth(), input.getHeight());
ThresholdImageOps.threshold(input, binary, threshold, false);
BufferedImage outputImage = VisualizeBinaryData.renderBinary(binary,null);
return outputImage;
}
The changes are ImageUInt8 => GrayU8 (etc.)
VisualizeBinaryData.renderBinary(binary,null) => ConvertBufferedImage.extractBuffered(binary)
It compiles - but haven't yet run it.
*/
public static BufferedImage boofCVBinarization(BufferedImage image, int threshold) {
GrayU8 input = ConvertBufferedImage.convertFrom(image,(GrayU8)null);
GrayU8 binary = new GrayU8(input.getWidth(), input.getHeight());
ThresholdImageOps.threshold(input, binary, threshold, false);
BufferedImage outputImage = ConvertBufferedImage.extractBuffered(binary);
return outputImage;
}

Related

Why does java.awt.Font.getStringBounds give different result on different machines?

I have an application that generates PDF reports (using JasperReports), however if I run my application on my development laptop the text fields have a slightly different size than when I generate the exact same report on the server. I eventually reduced the issue to the following code:
final Font font = Font.createFont(
Font.TRUETYPE_FONT,
MyTest.class.getResourceAsStream("/fonts/europa/Europa-Bold.otf")
).deriveFont(10f);
System.out.println(font);
System.out.println(font.getStringBounds(
"Text",
0,
4,
new FontRenderContext(null, true, true)
));
On my Laptop this prints:
java.awt.Font[family=Europa-Bold,name=Europa-Bold,style=plain,size=10]
java.awt.geom.Rectangle2D$Float[x=0.0,y=-9.90999,w=20.080002,h=12.669988]
On the server this prints:
java.awt.Font[family=Europa-Bold,name=Europa-Bold,style=plain,size=10]
java.awt.geom.Rectangle2D$Float[x=0.0,y=-7.6757812,w=20.06897,h=10.094452]
As you can see I actually ship the font file with the application, so I believe that there is no chance that both machines actually work with a different font.
I would have guessed that under these conditions the output of getStringBounds is system-independent. Obviously it is not. What could possibly cause the difference?
Disclaimer! : I'm not a font dev expert, just sharing my experience.
Yes, it's kind of native. Even new JavaFX web view for example, is depends on webkit.
If you dive into debugging for getStringBounds, you will realize it reaches a point, where font manager should decide to load a concreted font manager, where the class name is supposed to be system property sun.font.fontmanager.
Source code of sun.font.FontManagerFactory
...
private static final String DEFAULT_CLASS;
static {
if (FontUtilities.isWindows) {
DEFAULT_CLASS = "sun.awt.Win32FontManager";
} else if (FontUtilities.isMacOSX) {
DEFAULT_CLASS = "sun.font.CFontManager";
} else {
DEFAULT_CLASS = "sun.awt.X11FontManager";
}
}
...
public static synchronized FontManager getInstance() {
...
String fmClassName = System.getProperty("sun.font.fontmanager", DEFAULT_CLASS);
}
Those DEFAULT_CLASS values could validate your Obviously it is not. What could possibly cause the difference? mark.
The val for sun.font.fontmanager may be sun.awt.X11FontManager for some nix systems, but could be null for windows for instance, so the manager will be sun.awt.Win32FontManager.
Now each manager, may depends on vary underlying shaping/rendering engine/impl for sure(this may help).
Main reason could be the nature of fonts. As they are mostly vector stuffs. So based on platform/env, a rendered text could be bigger, or smaller. e.g., maybe windows apply desktop cleartype, and screen text size(DPI) on requested text rendering.
It seems, even if you have exactly two sun.awt.X11FontManager manager, the results will be vary. this may help too
If you just try out the sample code, on online compilers, you will face with vary results for sure.
Result of ideaone (https://ideone.com/AuQvMV), could not be happened, stderr has some interesting info
java.lang.UnsatisfiedLinkError: /opt/jdk/lib/libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory
at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2430)
at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2487)
at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2684)
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2638)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:827)
at java.base/java.lang.System.loadLibrary(System.java:1902)
at java.desktop/sun.font.FontManagerNativeLibrary$1.run(FontManagerNativeLibrary.java:57)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:310)
at java.desktop/sun.font.FontManagerNativeLibrary.<clinit>(FontManagerNativeLibrary.java:32)
at java.desktop/sun.font.SunFontManager$1.run(SunFontManager.java:270)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:310)
at java.desktop/sun.font.SunFontManager.<clinit>(SunFontManager.java:266)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:415)
at java.desktop/sun.font.FontManagerFactory$1.run(FontManagerFactory.java:82)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:310)
at java.desktop/sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74)
at java.desktop/java.awt.Font.getFont2D(Font.java:497)
at java.desktop/java.awt.Font.getFamily(Font.java:1410)
at java.desktop/java.awt.Font.getFamily_NoClientCode(Font.java:1384)
at java.desktop/java.awt.Font.getFamily(Font.java:1376)
at java.desktop/java.awt.Font.toString(Font.java:1869)
at java.base/java.lang.String.valueOf(String.java:3042)
at java.base/java.io.PrintStream.println(PrintStream.java:897)
at Ideone.main(Main.java:19)
Note the failed/missed load of libfreetype which is a native/C font rendering app
Result of coding ground (https://www.tutorialspoint.com/compile_java_online.php)
fnt manager: sun.awt.X11FontManager
java.awt.Font[family=Dialog,name=tahoma,style=plain,size=10]
java.awt.geom.Rectangle2D$Float[x=0.0,y=-9.282227,w=22.09961,h=11.640625]
Result of jdoodle (https://www.jdoodle.com/online-java-compiler/)
fnt manager: sun.awt.X11FontManager
java.awt.Font[family=Dialog,name=tahoma,style=plain,size=10]
java.awt.geom.Rectangle2D$Float[x=0.0,y=-9.839991,w=24.0,h=12.569988]
My machine
fnt manager: null
java.awt.Font[family=Tahoma,name=tahoma,style=plain,size=10]
java.awt.geom.Rectangle2D$Float[x=0.0,y=-10.004883,w=19.399414,h=12.0703125]
My Story (may help, you may try)
I had similar issue back in some years ago, where text rendering using exactly same embedded font failed on macOs/jdk8, for complex text rendering(lots of ligatures). Not just sizes, but also broken ligatures, kerning, etc...
I could fix my issue(cannot remember if fixed the sizing, but no broken ligatures for sure), using another workground, as following
InputStream is = Main.class.getResourceAsStream(fontFile);
Font newFont = Font.createFont(Font.TRUETYPE_FONT, is);
GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(newFont);
//later load the font by constructing a Font ins
Font f = new Font(name/*name of the embedded font*/, style, size);
Registering font using GraphicsEnvironment, and then instancing it using Font fixed our issue. So you may also give it a try.
Solution
Finally, I just step-down the jdk stuffs(it's really great pain in neck) for good, and came up with harfbuzz(shaping) + freetype(rendering) native impl that indeed was a peace in mind.
So...
• You may consider your production server(easy way) as reference for rendered font advance and rendering, and validate the result based on it(rather than dev machine)
• Or, use a cross and standalone (and probably native) shaping/rendering font engine/impl to make sure dev and production results will be the same.

Convert WGS84 lat/long to GGRS87

Hello I am using GMapsFX for my JavaFX application. I am getting longtitude and latitute from Google Maps with the API but I would like to get GGRS87 also.
In Greek it is called EGSA87. Ι have searched for that and found nothing so far. There might be a solution on the libraries of Geotools or proj4j but I don't have very good knowledge of java and especially I can't find the solutions in so big libraries like those.
I have found many sites to make calculations but how can I make a mathematical calculation myself? Or even a library to solve this problem?
You can use the GDAL library for it, but its setup is actually quite complicated. You would have to install GDAL on your system (it is in Debian packages) and then build the Java JNI bindings for it [1]. [2] is also quite useful in getting it to work.
Then, you could use the Java GDAL library:
<dependency>
<groupId>org.gdal</groupId>
<artifactId>gdal</artifactId>
</dependency>
and do something like:
final SpatialReference source = new SpatialReference();
source.ImportFromEPSG(4326); // EPSG code for WGS84, see www.epsg.io
final SpatialReference target = new SpatialReference();
target.ImportFromEPSG(4121); // EPSG code for GGRS87, see www.epsg.io
this.coordinateTransform = CoordinateTransformation.CreateCoordinateTransformation(source, target);
final Geometry geometry = ogr.CreateGeometryFromWkt(String.format("POINT (%f %f)", longitude, latitude));
geometry.Transform(coordinateTransform);
final double ggrsX = geometry.GetX();
final double ggrsY = geometry.GetY();
[1] https://trac.osgeo.org/gdal/wiki/GdalOgrInJavaBuildInstructionsUnix
[2] http://geoexamples.blogspot.com/2012/05/running-gdal-java.html

How to create a tensorflow serving client for the 'wide and deep' model?

I've created a model based on the 'wide and deep' example (https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/learn/wide_n_deep_tutorial.py).
I've exported the model as follows:
m = build_estimator(model_dir)
m.fit(input_fn=lambda: input_fn(df_train, True), steps=FLAGS.train_steps)
results = m.evaluate(input_fn=lambda: input_fn(df_test, True), steps=1)
print('Model statistics:')
for key in sorted(results):
print("%s: %s" % (key, results[key]))
print('Done training!!!')
# Export model
export_path = sys.argv[-1]
print('Exporting trained model to %s' % export_path)
m.export(
export_path,
input_fn=serving_input_fn,
use_deprecated_input_fn=False,
input_feature_key=INPUT_FEATURE_KEY
My question is, how do I create a client to make predictions from this exported model? Also, have I exported the model correctly?
Ultimately I need to be able do this in Java too. I suspect I can do this by creating Java classes from proto files using gRPC.
Documentation is very sketchy, hence why I am asking on here.
Many thanks!
I wrote a simple tutorial Exporting and Serving a TensorFlow Wide & Deep Model.
TL;DR
To export an estimator there are four steps:
Define features for export as a list of all features used during estimator initialization.
Create a feature config using create_feature_spec_for_parsing.
Build a serving_input_fn suitable for use in serving using input_fn_utils.build_parsing_serving_input_fn.
Export the model using export_savedmodel().
To run a client script properly you need to do three following steps:
Create and place your script somewhere in the /serving/ folder, e.g. /serving/tensorflow_serving/example/
Create or modify corresponding BUILD file by adding a py_binary.
Build and run a model server, e.g. tensorflow_model_server.
Create, build and run a client that sends a tf.Example to our tensorflow_model_server for the inference.
For more details look at the tutorial itself.
Just spent a solid week figuring this out. First off, m.export is going to deprecated in a couple weeks, so instead of that block, use: m.export_savedmodel(export_path, input_fn=serving_input_fn).
Which means you then have to define serving_input_fn(), which of course is supposed to have a different signature than the input_fn() defined in the wide and deep tutorial. Namely, moving forward, I guess it's recommended that input_fn()-type things are supposed to return an InputFnOps object, defined here.
Here's how I figured out how to make that work:
from tensorflow.contrib.learn.python.learn.utils import input_fn_utils
from tensorflow.python.ops import array_ops
from tensorflow.python.framework import dtypes
def serving_input_fn():
features, labels = input_fn()
features["examples"] = tf.placeholder(tf.string)
serialized_tf_example = array_ops.placeholder(dtype=dtypes.string,
shape=[None],
name='input_example_tensor')
inputs = {'examples': serialized_tf_example}
labels = None # these are not known in serving!
return input_fn_utils.InputFnOps(features, labels, inputs)
This is probably not 100% idiomatic, but I'm pretty sure it works. For now.

How can I display my example code in JavaDoc, without having to manually copy/paste it?

I need to display my example code directly in my library's JavaDoc documentation, including its output. But I want to automate this process, so the example code can be unit tested by an external process, and not displayed unless it actually works.
I have not figured out a way to do this except by manually copy-pasting the source code (and output) each time a change is made--which is unmanageable given there are now well above a hundred example classes in my various projects. Alternatively I could simply not display those examples, but instead provide a link to them.
Both of these solutions are unacceptable, and I am hoping there might be a better way to do this.
How do you automate the insertion of your example code, so it is displayed directly in your JavaDoc?
Thanks.
Not exactly what you want, but maybe another interesting approach is the documentation of the Play Framework:
They document with Markdown and integrate code samples with special annotations (described in the Guidelines for writing Play documentation). So all the code samples can be tested before they are included in the documentation.
Their (unfortunately custom) solution to generate the docs can be found in the play-doc GitHub repository.
This is the question I've tried to answer with Codelet (GitHub link).
Codelet automates the insertion of already unit-tested example code into your JavaDoc, using taglets. As with all taglets, Codelet is executed as part of javadoc.exe. It is now released in beta, (and needs beta testers!).
There are four Codelet taglets:
{#codelet.and.out}: Displays source code immediately followed by its output
{#codelet}: Displays source code only
{#codelet.out}: Displays output only
{#file.textlet}: Displays the contents of any plain-text file, such as the input for an example code.
A common example:
{#.codelet.and.out com.github.aliteralmind.codelet.examples.adder.AdderDemo%eliminateCommentBlocksAndPackageDecl()}
which uses the eliminateCommentBlocksAndPackageDecl() "customizer" to eliminate the package declaration line and all multi-line comments (such as the license and JavaDoc blocks).
Output (between the horizontal rules):
Example
public class AdderDemo {
public static final void main(String[] ignored) {
Adder adder = new Adder();
System.out.println(adder.getSum());
adder = new Adder(5, -7, 20, 27);
System.out.println(adder.getSum());
}
}
Output
0
45
An alternative is to display only a portion of the example's code: A code snippet:
{#.codelet.and.out com.github.aliteralmind.codelet.examples.adder.AdderDemo%lineRange(1, false, "Adder adder", 2, false, "println(adder.getSum())", "^ ")}
This displays the same example as above, starting with (the line containing) Adder adder, and ending with the second println(adder.getSum()). This also eliminates the extra indentation, which in this case is six spaces.
Output (between the horizontal rules):
Example
Adder adder = new Adder();
System.out.println(adder.getSum());
adder = new Adder(5, -7, 20, 27);
System.out.println(adder.getSum());
Output:
0
45
All taglets accept customizers.
It is possible to write your own customizers which, for example, can "linkify" function names, change the template in which source-and-output is displayed, and do any arbitrary alteration to any or all lines. Examples include highlighting something in yellow, or making regular expression replacements.
As a final example, and as a contrast to those above, here is the taglet that blindly prints all lines from an example code, without any changes. It uses no customizer:
{#.codelet.and.out com.github.aliteralmind.codelet.examples.adder.AdderDemo}
Output (between the horizontal rules):
Example
/*license*\
Codelet: Copyright (C) 2014, Jeff Epstein (aliteralmind __DASH__ github __AT__ yahoo __DOT__ com)
This software is dual-licensed under the:
- Lesser General Public License (LGPL) version 3.0 or, at your option, any later version;
- Apache Software License (ASL) version 2.0.
Either license may be applied at your discretion. More information may be found at
- http://en.wikipedia.org/wiki/Multi-licensing.
The text of both licenses is available in the root directory of this project, under the names "LICENSE_lgpl-3.0.txt" and "LICENSE_asl-2.0.txt". The latest copies may be downloaded at:
- LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
- ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
\*license*/
package com.github.aliteralmind.codelet.examples.adder;
/**
<P>Demonstration of {#code com.github.aliteralmind.codelet.examples.adder.Adder}.</P>
<P>{#code java com.github.aliteralmind.codelet.examples.AdderDemo}</P>
#since 0.1.0
#author Copyright (C) 2014, Jeff Epstein ({#code aliteralmind __DASH__ github __AT__ yahoo __DOT__ com}), dual-licensed under the LGPL (version 3.0 or later) or the ASL (version 2.0). See source code for details. <A HREF="http://codelet.aliteralmind.com">{#code http://codelet.aliteralmind.com}</A>, <A HREF="https://github.com/aliteralmind/codelet">{#code https://github.com/aliteralmind/codelet}</A>
**/
public class AdderDemo {
public static final void main(String[] ignored) {
Adder adder = new Adder();
System.out.println(adder.getSum());
adder = new Adder(5, -7, 20, 27);
System.out.println(adder.getSum());
}
}
Output:
0
45
Codelet is now released in beta. Please consider giving it a try, and posting your comments and criticisms in the GitHub issue tracker.

How to extract programmatically video frames?

I need programmatically extract frames from mp4 video file, so each frame goes into a separate file. Please advise on a library that will allow to get result similar to the following VLC command (http://www.videolan.org/vlc/):
vlc v1.mp4 --video-filter=scene --vout=dummy --start-time=1 --stop-time=5 --scene-ratio=1 --scene-prefix=img- --scene-path=./images vlc://quit
Library for any of these Java / Python / Erlang / Haskell will do the job for me.
Consider using the following class by Popscan. The usage is as follows:
VideoSource vs = new VideoSource("file://c:\test.avi");
vs.initialize();
...
int frameIndex = 12345; // any frame
BufferedImage frame = vs.getFrame(frameIndex);
I would personally look for libraries that wrap ffmpeg/libavcodec (the understands-most-things library that many encoders and players use).
I've not really tried any yet so can't say anything about code quality and ease, but the five-line pyffmpeg example suggests it's an easy option - though it may well be *nix-only.

Categories