java调用opencv的tracking算法(java调用c++工程)

一,opencv安装
需要安装依赖ffmpeg,opencv+opencv-contrib,
opencv的安装参照上一条博客:
https://blog.csdn.net/yuejing987/article/details/84986195

二,通过JNI来实现java和c++的映射
1.创建一个简单的Java类,文件名为Test.java

public class Test
{
    static {
        try{
            System.loadLibrary("Test");
        }catch(UnsatisfiedLinkError e){
            System.err.println("Cannot load Test library!\n");
        }
    }
    public Test()
    { }
    public native void TestTry();
}

2.生成Test.h文件:
(1)javac Test.java
(2)javah Test
此时就生成了一个Test.h文件。这个头文件就是根据JNI规则来生成了native方法,需要在c++文件来实现这个方法。

3.在与Test.h相同路径洗创建一个cpp文件main.cpp:

#include 
#include 
#include 
#include "Test.h"

using namespace cv;
using namespace std;

// Convert to string
#define SSTR( x ) static_cast< std::ostringstream & >( \
( std::ostringstream() << std::dec << x ) ).str()

JNIEXPORT void JNICALL Java_Test_TestTry(JNIEnv * env, jobject arg)
{
    cin.clear();
    cin.sync();

    // List of tracker types in OpenCV 3.2
    // NOTE : GOTURN implementation is buggy and does not work.
    string trackerTypes[6] = {"BOOSTING", "MIL", "KCF", "TLD","MEDIANFLOW", "GOTURN"};
    // vector  trackerTypes(types, std::end(types));

    // Create a tracker
    string trackerType = trackerTypes[2];

    Ptr tracker;

#if (CV_MINOR_VERSION < 3)
    {
        tracker = Tracker::create(trackerType);
    }
#else
    {
        if (trackerType == "BOOSTING")
            tracker=TrackerBoosting::create();
        if (trackerType == "MIL")
            tracker = TrackerMIL::create();
        if (trackerType == "KCF")
            tracker = TrackerKCF::create();
        if (trackerType == "TLD")
            tracker = TrackerTLD::create();
        if (trackerType == "MEDIANFLOW")
            tracker = TrackerMedianFlow::create();
        if (trackerType == "GOTURN")
            tracker = TrackerGOTURN::create();
    }
#endif
    // Read video
    //VideoCapture video("/home/cvpr/Videos/video");
    VideoCapture video("rtsp://admin:[email protected]//Streaming/Channels/1");
    // Exit if video is not opened
    if(!video.isOpened())
    {
        cout << "Could not read video file" << endl;
        return ;

    }

    // Read first frame
    Mat frame;
    bool ok = video.read(frame);

    // Define initial boundibg box
    Rect2d bbox(287, 23, 86, 320);

    // Uncomment the line below to select a different bounding box
    bbox = selectROI(frame, false);

    // Display bounding box.
    rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 );
    imshow("Tracking", frame);

    tracker->init(frame, bbox);

    while(video.read(frame))
    {
        // Start timer
        double timer = (double)getTickCount();

        // Update the tracking result
        bool ok = tracker->update(frame, bbox);

        // Calculate Frames per second (FPS)
        float fps = getTickFrequency() / ((double)getTickCount() - timer);

        if (ok)
        {
            // Tracking success : Draw the tracked object
            rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 );
        }
        else
        {
            // Tracking failure detected.
            putText(frame, "Tracking failure detected", Point(100,80), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0,0,255),2);
        }

        // Display tracker type on frame
        putText(frame, trackerType + " Tracker", Point(100,20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50,170,50),2);

        // Display FPS on frame
        putText(frame, "FPS : " + SSTR(int(fps)), Point(100,50), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50,170,50), 2);

        // Display frame.
        imshow("Tracking", frame);

        // Exit if ESC pressed.
        int k = waitKey(1);
        if(k == 27)
        {
          break;
        }

    }
}

把Test.h头文件加载进去,注意函数名称的改写,
如果这块儿不清楚的话,可以查看另一篇博客:
https://blog.csdn.net/yuejing987/article/details/84987552

4.然后修改你项目中的cmakelist.txt文件

cmake_minimum_required(VERSION 3.7)
project(Test)

find_package( OpenCV REQUIRED )

set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)

aux_source_directory(. Test_src)
add_library(Test SHARED ${Test_src})

#add_executable(Test ${SOURCE_FILES})

target_link_libraries( Test ${OpenCV_LIBS} )
set_target_properties(Test PROPERTIES output_name "Test")

其中加入了:
aux_source_directory(. Test_src)
add_library(Test SHARED ${Test_src})
set_target_properties(Test PROPERTIES output_name “Test”)

5.然后在当前目录下,执行:

cmake .
make

生成libTest.so文件

6.如果报如下错误:

Jni.h No such file or directory

把/usr/local/java/jdk1.8.0_191/include/路径下的jni.h和/usr/local/java/jdk1.8.0_191/include/linux/路径下的jni_md.h拷贝到当前路径下。
然后把Test.h文件中的

#include 

改为

#include "jni.h"

7,然后写一个简单的ToTest.java文件,调用它:

public class ToTest
{
    public static void main(String argv[])
    {
        ToTest say = new ToTest();
    }
    public ToTest()
    {
        Test h = new Test();
        h.TestTry();
    }
}

javac ToTest.java
java ToTest
就会发现,程序已启动。

你可能感兴趣的:(JNI)