Sunday, December 13, 2015

Develop OpenCV Cross Platform Applications with Java

Hi All,

Today I'm going to show you how you can start developing OpenCV applications with Java that can work independently from the underlying OS. This might not be the best implementation, but what I'm going to share works fine.

I assume you have some basic knowledge in working with OpenCV in Java. You can easily download OpenCV for Windos/Linux/Mac from OpenCV downloads. Here I'm going to use OpenCV 2.4.11. You can download your preferred version.

I'm going to use the following simple code to demonstrate that OpenCV is working.
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;

public class Main
{
 public static void main(String[] args)
 {
  System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
  Mat mat = Mat.eye(3, 3, CvType.CV_8UC1);
                System.out.println("mat = " + mat.dump());
 }
}

Our purpose here is to provide the above code to work in any platform. ( Here I'm going to show only for Windows and Linux. You can use similar method for Mac)

Therefore first we have to build necessary .dll and .so files so that we can use them in our application. For Windows it's very easy because, when you download OpenCV for windows and extract it to a particular location you can find the .dll files in \build\java\x64 and in \build\java\x86.

Next we have to build the .so files.

In your Linux machine that you are going to build .so files, make sure you have installed the following programs before you follow the next set of instructions.

1. g++
2. cmake
3. ant

You can install the above programs by just using 'sudo apt-get install ' .
Make sure you have set the Java path in your terminal before you execute the commands. You can use 'export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64' command to do this.

Once you have set up your environment you can use the following instructions to build the .jar and .so files for opencv.

1. Download OpenCV for Linux.
2. Extract the .zip file to a location.
3. CD into that location.
4. Execute the following commands.

mkdir release
cd release
cmake -DBUILD_SHARED_LIBS=OFF ..
make -j8
When you run the cmake -DBUILD_SHARED_LIBS=OFF .. command make sure you get the following output. Otherwise you won't get the .so and .jar files created.


Inside the release folder you can find the newly created files. Inside 'bin' folder you can find the 'opencv-2411.jar' and inside 'lib' folder you can find the 'libopencv_java2411.so' file.

You can build for both Linux 32 and 64 bit environments.

Now we are ready to develop our OpenCV program for both Windows and Linux environments along with their respective bitness (64 or 32).

I am using Eclipse to develop my application. First add the 'opencv-2411.jar' to your project and add it to the Build Path.

Then copy the .dll and .so files for both 32 and 64bit versions to a folder inside the project. Now with the following code, you can start loading the libraries for the respective OS.
if (os.toUpperCase().contains("WINDOWS"))
  {
   if (bitness.endsWith("64"))
   {
    lib = new File("native/64x" + System.mapLibraryName("opencv_java2411"));
   }
   else
   {
    lib = new File("native/86x" + System.mapLibraryName("opencv_java2411"));
   }
  }
  else if (os.toUpperCase().contains("LINUX"))
  {
   if (bitness.endsWith("64"))
   {
    lib = new File("native/64x" + System.mapLibraryName("opencv_java2411"));
   }
   else
   {
    lib = new File("native/86x" + System.mapLibraryName("opencv_java2411"));
   }
  }
  
  System.out.println(lib.getAbsolutePath());
  System.load(lib.getAbsolutePath());

Insert the above code block inside your class. Then you can run the previous demo code without using the 'System.loadLibrary(Core.NATIVE_LIBRARY_NAME);' line, because we have already loaded the library from the above block.

Following is the complete code. I have loaded the library inside the main method. In your applications you can use it inside a Static code block according to your application.
import java.io.File;

import org.opencv.core.CvType;
import org.opencv.core.Mat;

public class Main
{
 public static void main(String[] args)
 {
  File lib = null;
  String os = System.getProperty("os.name");
  String bitness = System.getProperty("sun.arch.data.model");
  
  if (os.toUpperCase().contains("WINDOWS"))
  {
   if (bitness.endsWith("64"))
   {
    lib = new File("lib/opencv/64x" + System.mapLibraryName("opencv_java2411"));
   }
   else
   {
    lib = new File("lib/opencv/86x" + System.mapLibraryName("opencv_java2411"));
   }
  }
  else if (os.toUpperCase().contains("LINUX"))
  {
   if (bitness.endsWith("64"))
   {
    lib = new File("lib/opencv/64x" + System.mapLibraryName("opencv_java2411"));
   }
   else
   {
    lib = new File("lib/opencv/86x" + System.mapLibraryName("opencv_java2411"));
   }
  }
  
  System.out.println(lib.getAbsolutePath());
  System.load(lib.getAbsolutePath());
  
  Mat mat = Mat.eye(3, 3, CvType.CV_8UC1);
        System.out.println("mat = " + mat.dump());
 }
}


Here my native .dll and .so files are inside a folder named 'lib/opencv/'.


You will get the following output. 

Hope this helps.

Thank you..

:-)

6 comments:

  1. Excellent job :) thank you very much for everything ^_^

    ReplyDelete
  2. Good Work Kinath...
    Thanks for sharing...

    ReplyDelete
  3. Hello Kinath,
    The Article Give Detail information about Develop OpenCV Cross Platform Applications with Java.It give Detail information about it ,Thanks for Sharing the information
    Xamarin Apps Development

    ReplyDelete