基于大疆MSDK的识别开发

使用MSDK实现自定义模型的识别检测功能

1、 在github上寻找开源的,部署到安卓平台的项目,最开始是在自己的手机上做实验,发现跑不通,寻找问题,最终是图像转换的问题。
2、 然后训练自己的代码,读程序,了解思路,C++,JNI因为我们需要实例分割与目标识别都需要,然后我创建了一个抽象的yolo类,通过多态的方式实现了针对不同的模型,目标检测与实例分割的结合的操作。
3、 加载航线模板,通过创建航线模板,进行数据替换的方式,完成航线模板的制作。
4、 程序的融合,由于遥控器平台是无人机推流的方式,所以需要进行桢监听的控制,出现了一个bug,模型切换与模型的执行是处于不同线程的函数,所以我通过加锁的方式实现了互斥
最终效果,实现了人体检测,请添加图片描述
在这里插入图片描述

cameraStreamManager.addFrameListener(LEFT_OR_MAIN, ICameraStreamManager.FrameFormat.RGBA_8888, (ICameraStreamManager.CameraFrameListener) (frameData, offset, length, width, height, format) -> {
                yolov8.byte2Mat(frameData, width, height, surfaceView.getHolder().getSurface(), res); //这里res返回5个值
                for (int item : res) {
                    Log.d("yolov8ncnnJava", "value " + item);
                }
               
                Log.d("yolov8ncnn", "return");
            });

这里调用了视频的监听函数,然后通过JNI调用C++编写的识别函数
在这里插入图片描述

#define TAG "yolov8ncnn"
JNIEXPORT void JNICALL Java_com_inspect_guangfu_Jninterface_Yolov8Ncnn_byte2Mat(JNIEnv *env, jobject thiz, jbyteArray in, jint w, jint h, jobject surface, jintArray res){
    jint len = env->GetArrayLength(res);
    jint * res_point = env->GetIntArrayElements(res, NULL);
    if(surface == NULL || surface == nullptr){
        __android_log_print(ANDROID_LOG_DEBUG, TAG, "surface null");
        return;
    }
    ANativeWindow* win = ANativeWindow_fromSurface(env, surface);
    if(win == nullptr || win == NULL){
        __android_log_print(ANDROID_LOG_DEBUG, TAG, "win null");
        return;
    }
    if(in == nullptr){
        __android_log_print(ANDROID_LOG_DEBUG, TAG, "in array null");
        return;
    }
    __android_log_print(ANDROID_LOG_DEBUG, TAG, "width %d", ANativeWindow_getWidth(win));
    __android_log_print(ANDROID_LOG_DEBUG, TAG, "height %d", ANativeWindow_getHeight(win));

    int32_t win_w = ANativeWindow_getWidth(win);
    int32_t win_h = ANativeWindow_getHeight(win);
    jsize length = env->GetArrayLength(in);
    jbyte *data = env->GetByteArrayElements(in, NULL);

    cv::Mat src(h, w, CV_8UC4, (unsigned char *)data);
    cv::Mat dst(h, w, CV_8UC3);

    cv::cvtColor(src, dst, cv::COLOR_RGBA2RGB);

    cv::resize(dst, dst, cv::Size(win_w, win_h));
    cv::resize(src, src, cv::Size(win_w, win_h));

    env->ReleaseByteArrayElements(in, data, 0);
    std::vector<Object> objects;
    std::vector<int>res_data;
    {
        ncnn::MutexLockGuard g(lock);
        if (g_yolo != nullptr || g_yolo != NULL ||g_yolo != 0) {
            g_yolo->detect(dst, objects, 0.5, 0.5, false);
            g_yolo->draw(dst, objects, res_data);  // 绘制图像,同时生成结果图
            cv::cvtColor(dst, dst, cv::COLOR_RGB2RGBA);
            if(g_yolo->getReturnNum() == 2&&!res_data.empty()){
                memcpy(res_point, res_data.data(), len * sizeof(int));
//                for (int i = 0; i < 4; ++i) {
//                    __android_log_print(ANDROID_LOG_DEBUG, TAG, "res_point %d", res_point[i]);
//                    __android_log_print(ANDROID_LOG_DEBUG, TAG, "res_data %d", res_data[i]);
//                }
                env->ReleaseIntArrayElements(res, res_point, 0);
            }
        }
    }
    ANativeWindow_setBuffersGeometry(win, win_w, win_h, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM);
    ANativeWindow_Buffer windowBuffer;
    if(int err = ANativeWindow_lock(win, &windowBuffer, nullptr)){
        ANativeWindow_release(win);
        return;
    }
    else{
        memcpy(windowBuffer.bits, dst.data, windowBuffer.width * windowBuffer.height * 4);
        if(int err = ANativeWindow_unlockAndPost(win))
            __android_log_print(ANDROID_LOG_DEBUG, "yolov8ncnn", "error code: %s", strerror(err));
    }
    ANativeWindow_release(win);

    return;

}

函数内部完成识别、绘制、以及视频流装载的功能。如有需要可以一起讨论。这里主要涉及到一些图像转换的基本知识。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值