Java服务器部署基于OpenCV的C++图像处理项目(二)编译篇

Java服务器部署基于OpenCV的C++图像处理项目(二)编译篇

部署好环境之后,本篇记录编译的详细步骤。部署环境篇

1.创建文件

Java服务器部署基于OpenCV的C++图像处理项目(二)编译篇
在native.cpp中写入以下代码。

#include <jni.h>
#include <string>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>

extern "C" {

using namespace cv;
using namespace std;

	JNIEXPORT jintArray JNICALL Java_opencv_opencvImp_gray(
	    JNIEnv *env,
	    jclass jcls,
	    jintArray buf,
	    jint w,
	    jint h) {
	jint *cbuf = env->GetIntArrayElements(buf, JNI_FALSE );
	if (cbuf == NULL) { return 0; }
	Mat imgData(h, w, CV_8UC4, (unsigned char *) cbuf);
	uchar* ptr = imgData.ptr(0);
	for(int i = 0; i < w*h; i ++){
	    //计算公式:Y(亮度) = 0.299*R + 0.587*G + 0.114*B
	    // 对于一个int四字节,其彩色值存储方式为:BGRA
	    int grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.114);
	    ptr[4*i+1] = grayScale; ptr[4*i+2] = grayScale;
	    ptr[4*i+0] = grayScale;
	}
	int size = w * h;
	jintArray result = env->NewIntArray(size);
	env->SetIntArrayRegion(result, 0, size, cbuf);
	env->ReleaseIntArrayElements(buf, cbuf, 0);
	printf("Hello from opencv++!\n");
	return result;
	}

	JNIEXPORT void JNICALL Java_opencv_opencvImp_stringFromJNI(
		JNIEnv* env,
		jclass jcls) {
	printf("Hello from C++!\n");
	}
}

继续创建文件,

vi CMakeLists.txt

写入以下代码:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

#cmake version
cmake_minimum_required(VERSION 2.8)

#设置OpenCv的路径变量,这里的/app/opencv即是opencv的安装目录
set(pathToOpenCv /app/opencv) 
set(PROJECT_SOURCE_DIR /root/cmake_opencv_imp) 

#支持-std=gnu++11
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")

#配置加载native依赖,这里加入自己的jdk路径。
include_directories(${pathToOpenCv}/include /usr/local/java/jdk1.8.0_191/include /usr/local/java/jdk1.8.0_191/include/linux)

#表示创建一个导入库,静态方式
add_library(lib_opencv STATIC IMPORTED )

#引入libopencv_java3.so文件
set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION ${pathToOpenCv}/share/OpenCV/java/libopencv_java341.so )

# 自己的源文件
add_library( 
	  # Sets the name of the library.
        native

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        ./native.cpp
        )

#链接库
target_link_libraries(
        # Specifies the target library.
        native

        # Links the target library to the lib_opencv library  
        lib_opencv
)

至此准备工作完成

2.编译

命令如下

mkdir build
cd build
cmake -D CMAKE_INSTALL_PREFIX=/root/cmake_opencv_imp/build ..
make

Java服务器部署基于OpenCV的C++图像处理项目(二)编译篇

至此so库编译成功,将libnative.so拷贝到库搜索路径,例如:

cp libnative.so /usr/lib64

3.调用so库

在工程中的opencvImp中写入代码:

package opencv;

public class opencvImp {

    static {
    	// 打印库搜索路径,一般有很多个
        System.out.println(System.getProperty("java.library.path"));
		// 加载so库
        System.loadLibrary("native");
    }

    public static void check() {

        stringFromJNI();

        int w = 99, h = 99;
        int[] pix = new int[w * h];
        int[] resultPixes=gray(pix,w,h);
    }

	// 声明方法,和native.cpp中方法对应。
    public static native int[] gray(int[] buf, int w, int h);
    public static native void stringFromJNI();

}

启动程序时System.loadLibrary("native"); 会在默认路径中搜索 libnative. so,这里load方法中只需要写成native,不用加lib以及so后缀。
Java服务器部署基于OpenCV的C++图像处理项目(二)编译篇

在需要的类中直接调用即可:

import opencv.opencvImp;
public static void main(){
        opencvImp.check();
        System.out.println("成功调用!");
}

此时已经完成了opencv的调用,直接运行main
Java服务器部署基于OpenCV的C++图像处理项目(二)编译篇

由于测试方法没有实际体现,此处打印成功即表示之前的opencv调用没有问题,打印顺序暂时不知道是什么原因,如果有问题会报错。

到这一步编译打包基本就已经完成了,将这个工程打包传到服务器,使用java运行就可以了。