android 引入图像处理库OpenCV

作者: 小小混世魔王 | 来源:发表于2019-03-21 19:05 被阅读246次

    这里省去ndk开发环境的配置 直接进入opencv集成到Android studio中
    我们在opencv官网下载到的https://opencv.org android开发包 解压压缩包结构

    U$MD9(`)]]TK6WHT8H`O470.png
    在项目的main文件下新建jniLibs目录 将opencv的.so文件拷贝到该目录下 ss.png
    将opencv的include文件夹拷贝到cpp文件夹下
    includ.png
    配置cmake文件
    
    # 设置include文件夹的地址
    include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include)
    
    # 设置opencv的动态库
    add_library(libopencv_java3
            SHARED
            IMPORTED)
    
    set_target_properties(libopencv_java3
            PROPERTIES
            IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libopencv_java3.so)
    
    
    target_link_libraries( # Specifies the target library.
            native-lib libopencv_java3 jnigraphics
    
            # Links the target library to the log library
            # included in the NDK.
            ${log-lib})
    

    build.gradle文件 android 节点下配置

    android {
    .......
      sourceSets {
              main {
                  jniLibs.srcDirs = ['src/main/jniLibs']
              }
          }
    .......
    

    到此我们opencv 已经配置完成 下面我们来写一个小demo验证是否配置成功

    public class MainActivity extends AppCompatActivity {
        // Used to load the 'native-lib' library on application startup.
        static {
            System.loadLibrary("native-lib");
        }
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ImageView iv_show = findViewById(R.id.iv_show);
    
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.zyz);
    
            BitmapUtils.counterWorld(bitmap);
    
            iv_show.setImageBitmap(bitmap);
    
        }
    
    }
    

    下面是利用opencv 实现的一个逆世界效果

    #include <jni.h>
    #include <string>
    #include<opencv2/opencv.hpp>
    #include "bitmap/com_youyangbo_opencv_BitmapUtils.h"
    #include "bitmap/opencvHelp.h"
    
    
    using namespace cv;
    
    
    extern "C" void JNICALL Java_com_youyangbo_opencv_BitmapUtils_counterWorld
            (JNIEnv *env, jclass jclazz, jobject bitmap) {
    
    
        Mat src;
    
        bitmap2Mat(env, src, bitmap);
        int middleRows = src.rows >> 1;
        int quarterRows = middleRows >> 1;
        Mat conword_imag(src.size(), src.type());
    
        for (int row = 0; row < middleRows; ++row) {
    
            for (int col = 0; col < src.cols; ++col) {
    
                conword_imag.at<float>(middleRows + row, col) = src.at<float>(
                        quarterRows + row, col);
            }
    
        }
    
    
        for (int row = 0; row < middleRows; ++row) {
            for (int col = 0; col < src.cols; ++col) {
                conword_imag.at<float>(middleRows - row, col) = src.at<float>(quarterRows + row, col);
            }
        }
    
    
        mat2Bitmap(env, conword_imag, bitmap);
    }
    
    
    
    

    opencv 是c/c++的库,处理图片数据是Mat(矩阵),Android 图片表现形式是Bitmap,所以Android中的图片交给opencv处理必须先将Bitmap转化成Mat,

    #include "bitmap/opencvHelp.h"
    #include <android/log.h>
    
    /**
     * bitmap 转化为矩阵(Mat)
     * @param pEnv
     * @param mat
     * @param bitmap
     */
    void bitmap2Mat(JNIEnv *env, cv::Mat &mat, jobject bitmap) {
    
        AndroidBitmapInfo bitmap_info;
        void *pPixel = NULL;
    
        AndroidBitmap_getInfo(env, bitmap, &bitmap_info);
    
        AndroidBitmap_lockPixels(env, bitmap, &pPixel);
    
    
    
        //判断传入的图片是什么类型
        if (bitmap_info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {//32
            //对应opncv Mat 类型  CV_8UC4
            cv::Mat temp(bitmap_info.height, bitmap_info.width, CV_8UC4, pPixel);
            temp.copyTo(mat);
    
    
        } else if (bitmap_info.format == ANDROID_BITMAP_FORMAT_RGB_565) {//16
            //对应opncv Mat 类型  CV_8UC2
    
            cv::Mat temp(bitmap_info.height, bitmap_info.width, CV_8UC2, pPixel);
    
            cv::cvtColor(temp, mat, CV_BGRA2BGR565);
    
        }
    
    
        AndroidBitmap_unlockPixels(env, bitmap);
    }
    
    
    /**
     * Mat转化为Bitmap
     * @param pEnv
     * @param mat
     * @param bitmap
     */
    void mat2Bitmap(JNIEnv *env, cv::Mat &mat, jobject bitmap) {
        AndroidBitmapInfo bitmap_info;
        void *pPixel = NULL;
    
        AndroidBitmap_lockPixels(env, bitmap, &pPixel);
    
        AndroidBitmap_getInfo(env, bitmap, &bitmap_info);
    
        //判断传入的图片是什么类型
        if (bitmap_info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {//32
            cv::Mat tmp(bitmap_info.height, bitmap_info.width, CV_8UC4, pPixel);
            //对应opncv Mat 类型  CV_8UC4
            if (mat.type() == CV_8UC4) {
                //对应bitmap   RGBA_8888
                mat.copyTo(tmp);
    
            } else if (mat.type() == CV_8UC2) {
                //对应bitmap   RGB_565
                cv::cvtColor(mat, tmp, CV_BGR5652BGRA);
    
    
            } else if (mat.type() == CV_8UC1) {
                //单通道 0-255 的灰度图
                cv::cvtColor(mat, tmp, CV_GRAY2BGRA);
    
            }
    
        } else if (bitmap_info.format == ANDROID_BITMAP_FORMAT_RGB_565) {//16
            cv::Mat tmp(bitmap_info.height, bitmap_info.width, CV_8UC2, pPixel);
            //对应opncv Mat 类型  CV_8UC2
            if (mat.type() == CV_8UC4) {
                //对应bitmap   RGBA_8888
                cv::cvtColor(mat, tmp, CV_BGRA2BGR565);
    
            } else if (mat.type() == CV_8UC2) {
                //对应bitmap   RGB_565
    
                mat.copyTo(tmp);
    
            } else if (mat.type() == CV_8UC1) {
                //单通道 0-255 的灰度图
    
                cv::cvtColor(mat, tmp, CV_GRAY2BGR565);
            }
    
        }
    
    
        AndroidBitmap_unlockPixels(env, bitmap);
    
    }
    

    代码运行效果:

    原图: 2.jpg
    经过opencv处理过的 demo.png

    相关文章

      网友评论

        本文标题:android 引入图像处理库OpenCV

        本文链接:https://www.haomeiwen.com/subject/wzbcvqtx.html