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

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

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

1.创建文件

在这里插入图片描述
在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 void JNICALL Java_opencv_opencvImp_stringFromJNI(
		JNIEnv* env,
		jclass jcls) {
		
		printf("Hello from C++!\n");
	}
	JNIEXPORT void JNICALL Java_opencv_opencvImp_gray(
            JNIEnv *env,
            jclass jcls,
            jlong jin,
            jlong jout) {

            cv::Mat & in = *(Mat*)jin;
            cv::Mat & gray = *(Mat*)jout;
            cv::cvtColor(in, gray, CV_BGR2GRAY);
            printf("Hello from opencv++!\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

在这里插入图片描述

错误:‘JNIEXPORT’不是一个类型名,注意需编译的文件中#include <jni.h>

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

cp libnative.so /usr/lib64

3.调用so库

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

package opencv;

import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;

public class opencvImp {

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

	public static void check() {
	
		stringFromJNI();
		
		// 这里根据自己项目地址加载图片
		Mat srcmat = Imgcodecs.imread(opencvImp.class.getResource("/").getPath()+"image/tt1t.jpg");  
		Mat outmat = new Mat();
		gray(srcmat.getNativeObjAddr(),outmat.getNativeObjAddr());
	}

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

}

启动程序时System.loadLibrary("native"); 会在默认路径中搜索 libnative. so,这里load方法中只需要写成native,不用加lib以及so后缀。
在这里插入图片描述

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

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

此时已经完成了opencv的调用,直接运行main
在这里插入图片描述

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

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

在后续开发中,调用时遇到链接错误,我这里遇到这个错是由于代码是使用c++语法,存在函数名相同但参数不同的函数,编译时却没有报错,调用的时候就错了。我修改了其中一个函数名就可以了

[Handler dispatch failed; nested exception is java.lang.UnsatisfiedLinkError: opencv.opencvImp.decodetlevel(JJI)V] with root cause
java.lang.UnsatisfiedLinkError: opencv.opencvImp.decodetlevel(JJI)V
	at opencv.opencvImp.decodetlevel(Native Method) ~[xcx_checkmark-0.0.1-SNAPAHOT.jar!/:0.0.1-SNAPSHOT]
	...

参考资料:
https://yiheng.github.io/2016/06/01/build-jni-project-with-maven/

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值