(1)C接口中的接口頭文件
#pragma once #include <iostream> #include <vector> #include <core/core.hpp> #include <highgui/highgui.hpp> #include <imgproc/imgproc.hpp> #ifdef VIDEOPOSITION_EXPORTS #define VIDEOPOSITION_API __declspec(dllexport) #else #define VIDEOPOSITION_API __declspec(dllimport) #endif // VISION_EXPORTS using namespace std; using namespace cv; typedef void(*Callback_ColorPos)(int color, float fX,float fY); typedef void(*Callback_ImageOK)(int status); extern "C" int VIDEOPOSITION_API ColorPos(Callback_ColorPos GetColorPos,Callback_ImageOK GetImageSttus); extern "C" int VIDEOPOSITION_API OpenCamera(int index); extern "C" int VIDEOPOSITION_API CloseCamera();
我們可以看到,接口頭文件中有三個函數,其中有一個函數的參數有兩個回調類型。
(2)java中jna回調類的實現
package com.wxyz.scene_demonstration; import com.sun.jna.Callback; /** * 圓餅顏色和位置的回調接口 * * @author dengchaoqun * */ public interface ColorPosListener extends Callback {//定義一個接口繼承自jna的Callback類,對應上述頭文件中Callback_ColorPos回調 /** * 回調方法 * * @param color * 圓餅的顏色 * @param x * 圓餅的x軸坐標 * @param y * 圓餅的y軸坐標 */ public void Status(int color, float x, float y);//對應C中回調接口中的三個參數,(對應上述頭文件中Callback_ColorPos回調中的三個參數)
}
(3)java回調接口的實現,實現ColorPosListener這個接口,實現Status方法,當動態庫中有數據時, 數據就會傳遞到Status方法中的三個參數中,這樣java端就可以監聽動態庫中的數據,並處理。
java對應動態庫的接口如下
package com.wxyz.scene_demonstration; import com.sun.jna.Library; import com.sun.jna.Native; /** * 動態規整接口 * * @author dengchaoqun * */ public interface SceneDemo2API extends Library { SceneDemo2API INSTANCE = (SceneDemo2API) Native.loadLibrary("VideoPosition", SceneDemo2API.class); public int OpenCamera(int item);// 打開攝像頭接口方法 public int ColorPos(ColorPosListener GetColorPos, ImageOKListener GetImage);// 回調獲取數據的方法 public int CloseCamera();// 關閉攝像頭的方法 }
java接口對應的實現類如下,以及使用demo如下
package com.wxyz.scene_demonstration; @SuppressWarnings("unused") public class SceneDemo2Control { private static boolean cameraStatus = true;// 相機打開的狀態,默認關閉 private static final float Y_point = 80.0f;// 圖像識別原點在機械臂坐標系中y軸方向的坐標值 private static final float Z_point = -312.5f;// 圖像識別原點在機械臂坐標戲中z軸方向的坐標值,也就是吸圓餅的坐標值 private static final float s = 339.5f;// 圓餅數據發送點距離機械臂原點的x軸方向的距離,用於計算時間來用。 /** * 回調監聽攝像頭回傳的圓餅數據,以及圖片是否寫好了的監聽 * * @param listener * 監聽器,用戶在使用的時候需要實現一個ColorPosListener接口,當有數據返回的時候就可以實時獲取動態庫回傳的數據 * image * 監聽器,用戶在使用的時候需要實現一個ImageOKListener接口,20ms拍一張圖片,當圖片寫好后,返回1, * 可更新界面imageView * @return 狀態碼 該方法是一個延時的方法,在攝像頭打開后,會一直執行,在這個過程中只有當攝像頭關閉后才會返回-1值 */ public static int getColorPos(ColorPosListener listener, ImageOKListener image) { if (cameraStatus == false) { System.out.println("攝像頭沒打開,請先成功的打開攝像頭!"); return -1; } else { int status = SceneDemo2API.INSTANCE.ColorPos(listener, image); return status; } } /** * 打開攝像頭 * * @param item * 表示是哪一個攝像頭,從0開始 * @return 打開攝像頭的狀態,-1表示打開失敗,0表示打開成功 */ public static int openCamera(int item) { int status = SceneDemo2API.INSTANCE.OpenCamera(item); if (status == 0) { cameraStatus = true; System.out.println("攝像頭打開成功!"); } else { cameraStatus = true; System.out.println("攝像頭打開失敗!"); } return status; } /** * 關閉攝像頭的方法 * * @return 狀態嗎,-1表示關閉失敗,0表示關閉成功 */ public static int closeCamera() { int status = SceneDemo2API.INSTANCE.CloseCamera(); if (status == 0) { cameraStatus = true; System.out.println("攝像頭關閉成功!"); } else { cameraStatus = true; System.out.println("攝像頭關閉失敗!"); } return status; } // demo public static void main(String[] args) { openCamera(1); getColorPos(new ColorPosListener() { @Override public void Status(int color, float x, float y) { // color的對應關系,0紅色,1綠色,2藍色,3黃色,4白色,5紫色 x = Math.round(x);// 吸球點的x坐標系是固定,需要根據實際的去定位吸球的 y = Math.round(y) - Y_point; if (color == 1) {// 假定兩種顏色分別是1,2 // 調用運動方法,氣嘴吸餅,運動到指定的一邊 } else if (color == 2) { // 調用運動方法,氣嘴吸餅,運動到指定的一邊 } System.out.println(x + "::" + y); } }, new ImageOKListener() { @Override public void GetImage(int imgReady) { // TODO Auto-generated method stub if (imgReady == 1) {// 圖片寫好了 // 更新imageView的值 } else if (imgReady == 0) {// 正在寫圖片 } } }); closeCamera(); } }