Load OpenCV's ML (SVM) from string - android

I'm currently developing an algorithm for texture classification based on Machine Learning, primarily Support Vector Machines (SVM). I was able to gain some very good results on my test data and now want to use the SVM in productive environment.
Productive in my case means, it is going to run on multiple Desktop- and Mobile platforms (i.e. Android, iOS) and always somewhere deep down in native threads. For reasons of software structure and the platform's access policies, I'm not able to access the file system from where I use the SVM. However, my framework supports reading Files in an environment where access the file system is granted and channel the file's content as a std::string to the SVM-part of my application.
The standard procedure how to configure an SVM is by using filenames and OpenCV reads directly from the file:
cv::SVM _svm;
_svm.load("/home/<usrname>/DEV/TrainSoftware/trained.cfg", "<trainSetName>");
I want this (basically reading from the file somewhere else and passing the file's content as a string to the SVM):
cv::SVM _svm;
std::string trainedCfgContentStr="<get the content here>";
_svm.loadFromString(trainedCfgContentStr, "<trainSetName>") // This method is desired
I couldn't find anything in OpenCV's docs or source that this is possible somehow, but it wouldn't be the first OpenCV-Feature that's there and not documented or widely known. Of course, I could hack the OpenCV source and cross-compile to each of my target platforms, but I'd try to avoid that since it is a hell lot of work, besides I'm pretty convinced I'm not the first one with this problem.
All ideas (also unconventional) and/or hints are highly appreciated!

as long as you stick with the c++ api it's quite easy, FileStorage can read from memory:
string data_string; //containing xml/yml data
FileStorage fs( data_string, FileStorage::READ | FileStorage::MEMORY);
svm.read(fs.getFirstTopLevelNode()); // or the node with your trainset
(unfortunately not exposed to java)

Related

image decoding and manipulation using JNI on android

background
On some apps, it is important to handle large images without OOM and also quickly.
For this, JNI (or renderscript, which sadly lacks on documentation) can be a nice solution.
In the past, i've succeeded using JNI for rotating huge bitmaps while avoiding OOM (link here , here and here). it was a nice (yet annoyingly hard) experience, but in the end it worked.
the problem
the android framework has plenty of functions to handle bitmaps, but i have no idea what is the situation on the JNI side.
I already know how to pass a bitmap from android's "java world" to the "JNI world" and back.
What i don't know is which functions I can use on the JNI side to help me with bitmaps.
I wish to be able to do all image operations (including decoding) on JNI, so that I won't need to worry about OOM when presented with large images, and in the end of the process, I could convert the data to Java-bitmap (to show the user) and/or write it to a file.
again, i don't want to convert the data on the JNI side to a java bitmap just to be able to run those operations.
As it turns out, there are some libraries that offer many functions (like JavaCV), but they are quite large and I'm not quite sure about their features and if they really do the decoding on the JNI-side, so I would prefer to be able to know what is possible via the built-in JNI function of Android instead.
the question
which functions are available for image manipulation on the JNI side on android?
for example, how could i run face detection on bitmaps, apply matrices, downsample bitmaps, scale bitmaps, and so on... ?
for some of the operations, i can already think of a way to implement them (scaling images is quite easy, and wikipedia can help a lot), but some are very complex.
even if i do implement the operations by myself, maybe others have made it much more efficiently, thinking of the so many optimizations that C/C++ can have.
am i really on my own when going to the JNI side of android, where i need to implement everythign from scratch?
just to make it clear, what i'm interested in is:
input bitmap on java -> image manipulation purely in JNI and C/C++ (no convertion to java objects whatsoever) ->output bitmap on java.
"built-in JNI function of Android" is kind of oxymoron. It's technically correct that many Android Framework Java classes use JNI somewhere down the chain to invoke native libraries.
But there are three reservations regarding this statement.
These are "implementation details", and are subject to change without notice in any next release of Android, or any fork (e.g. Kindle), or even OEM version which is not regarded a "fork" (e.g. built by Samsung, or for Quallcom SOC).
The way native methods are implemented in core Java classes is different from the "classical" JNI. These methods are preloaded and cached by the JVM and are therefore do not suffer from most of the overhead typical for JNI calls.
There is nothing your Java or native code can do to interact directly with the JNI methods of other classes, especially classes that constitute the system framework.
All this said, you are free to study the source code of Android, to find the native libraries that back specific classes and methods (e.g. face detection), and use these libraries in your native code, or build a JNI layer of your own to use these libraries from your Java code.
To give a specific example, face detection in Android is implemented through the android.media.FaceDetector class, which loads libFFTEm.so. You can look at the native code, and use it as you wish. You should not assume that libFFTEm.so will be present on the device, or that the library on device will have same API.
But in this specific case, it's not a problem, because all work of neven is entirely software based. Therefore you can copy this code in its entirety, or only relevant parts of it, and make it part of your native library. Note that for many devices you can simply load and use /system/lib/libFFTEm.so and never feel discomfort, until you encounter a system that will misbehave.
One noteworthy conclusion you can make from reading the native code, is that the underlying algorithms ignore the color information. Therefore, if the image for which you want to find face coordinates comes from YUV source, you can avoid a lot of overhead if you call
// run detection
btk_DCR_assignGrayByteImage(hdcr, bwbuffer, width, height);
int numberOfFaces = 0;
if (btk_FaceFinder_putDCR(hfd, hdcr) == btk_STATUS_OK) {
numberOfFaces = btk_FaceFinder_faces(hfd);
} else {
ALOGE("ERROR: Return 0 faces because error exists in btk_FaceFinder_putDCR.\n");
}
directly with your YUV (or Y) byte array, instead of converting it to RGB and back to YUV in android.media.FaceDetector.findFaces(). If your YUV buffer comes from Java, you can build your own class YuvFaceDetector which will be a copy of android.media.FaceDetector with the only difference that YuvFaceDetector.findFaces() will take Y (luminance) values only instead of a Bitmap, and avoid the RGB to Y conversion.
Some other situations are not as easy as this. For example, the video codecs are tightly coupled to the hardware platform, and you cannot simply copy the code from libstagefright.so to your project. Jpeg codec is a special beast. In modern systems (IIRC, since 2.2), you can expect /system/lib/libjpeg.so to be present. But many platforms also have much more efficient HW implementations of Jpeg codecs through libstagefright.so or OpenMAX, and often these are used in android.graphics.Bitmap.compress() and android.graphics.BitmapFactory.decode***() methods.
And there also is an optimized libjpeg-turbo, which has its own advantages over /system/lib/libjpeg.so.
It seems that your question is more about C/C++ image processing libraries than it is about Android per se. To that end, here are some other StackOverflow questions that might have information you'd find useful:
Fast Cross-Platform C/C++ Image Processing Libraries
C++ Image Processing Libraries

How to encode sounds on android? [duplicate]

How can we make Android assets secure so that no one can read them after app deployment?
There is nothing you can do that will stop a determined attacker from reading them.
Using your own application level encryption would at least make the problem unique to your application, but someone could still do code analysis of your app to figure out how to decrypt them.
The platform's limited copy protection mechanisms are weaker, because they only have to be defeated once for all applications (such as by rooting the phone).
Assets utilized by platform functionality would also vulnerable to a modified platform configured to dump out copies of them.
Do what is easy to stop casual copying by unsophisticated users if you like, but then save your time and energy for battles you can actually win, such as the quality of your application.

Free Fuzzy Logic Library, can't parse a file on android

I am developing an application for android/iOS/windows using c++ code for the core logic. The application uses the free fuzzy logic library and it works perfectly for windows mobile, iOS and on my local Ubuntu machine, but it doesn't quite work under android.
The application reads a .fcl file from the sd card and then parses it using the free fuzzy logic library parser. The problem is, that the parser gets stuck at random stages of parsing.
Some notes to my project settings:
I enabled the Android read/write permissions for the sdcard in the manifest.xml.
The code I am trying to run is the basic example from the free fuzzy logic library website.
I am using the stlport_static library for stl support and the -frtti compiler flag.
My question is: Am I missing something android specific, like file encoding or some permissions I didn't set?
Some notes I thought about:
File compression should not be an issues, because, to my knowledge, files on the SD card are not compressed and I can parse the file partially.
Using other fuzzy logic libraries is out of the option, because I can't use GPL licenced libraries. The only other library I found didn't hat a manual / how to and couldn't parse the fcl standard.
The free fuzzy logic library uses a lot of wchar_t's whitch could be an issue.
Thank you for your time and hopefully for some help ;)
Ok after plowing through some android manuals and some Google abuse I found the problem. Currently Android doesn't support the wchar_t type. Well you can use it, but the results will not be the same as on any other operating system.
By changing all the wchar_t and wstring types in the free fuzzy logic library to their corresponding char and string types I was able to make the parser work. Well sort of, there are still some sleight inconsistencies, but nothing i can't handle ;).
Conclusion: Don't use wide characters in android c++ Programs.
Thank you for your time & help

Data compression on Android (other than java.util.zip ?)

I have a lot of data (text format) to send from a device. It obviously means that I should compress it. But my question is whether there are any ways of doing it other than by zip algorithm (like this). The reason I am asking this question is over here - for a text file i.e. 7-zip is twice (!) better than zip. Which is a significant gain. And maybe there are even better algorithms.
So are there any effective ways of data compression (better than zip) available for Android?
You would need to compile another library into your code, since I doubt that compression algorithms other than zlib are available as part of the standard libraries on the Android.
The 7-zip algorithm you refer to is actually called LZMA, which you can get in library form in the LZMA SDK. The source code is available in Java as well as C. If you can link C code into your application, that would be preferable for speed.
Since there's no such thing as a free lunch, the speed is important. LZMA will require much more memory and much more execution time to achieve the improved compression. You should experiment with LZMA and zlib on your data to see where you would like the tradeoff to fall between execution time and compression, both to choose a package and to pick compression levels within a package.
If you find that you'd like to go the other way, to less compression and even higher speed than zlib, you can look at lz4.
Your question is too general.
You can use any library, as long as it is in Java or C/C++ (via the NDK). If you don't want to use external libraries, you have to stick to what's in the SDK. Depending on how you are sending the data, there might be standard ways to do this. For example, HTTP uses gzip and has the necessary headers already defined.
In short, test different things with your expected data format and size, find the best one and integrate it in your app.

forensic tool for Android

I am doing a forensic course and as a requirement I have been asked to develop a forensic investigation tool (windows based) for Google's Android OS. The requirement is such that given an image file, the tool should be able to display the databases that the applications are using, call history, messages and etc..
I have little experience in Java but I have no experience in Android development. The research so far has given me nothing on how to go about this. If anyone could point me in the right direction I would much appreciate it.
Thanks in advance.
Step 1 would be mounting the filesystem. Since Android is Linux based, there's a huge array of filesystems available, and individual vendors may or may not decide to write their own filesystems, just for the fun of it. On Windows, your options include ext2fsd or ext2read, among other possibilities.
Once you've got the filesystem mounted, then you get to deal with the per-application data storage. I'd wager a fair amount of applications use SQLite3, because it is an amazing tool. But you'll have to figure out, for each type of data you want to read, where it is stored and in what format. (The standard file(1) tool on Linux systems can come in handy, it knows heuristics that are surprisingly good at showing what type of file you might be dealing with.)
If you have the .apk of an application, a tool such as dex2jar, used in combinaison with something like jd-gui, can get you the JAVA source-code of the application (which can help, if not obfuscated).
After that, an .apk is basically a zip-file -- which means opening it with an unzip-ing application will allow you to get the images and resources it uses.
Then, databases used by Android applications tend to be SQLite, on which you can do SQL queries, using an SQLite client.

Categories

Resources