美文网首页
Android高级 opencv

Android高级 opencv

作者: LiuJP | 来源:发表于2020-09-17 11:40 被阅读0次

Android opencv sdk ndk 接入方法
https://www.jianshu.com/p/6e16c0429044

opencv 常用api

1、截屏

package com.qxtool;

import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Build;
import android.os.Environment;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;

public class BMPUtils {


    private Point Hµ;


    static {//加载so库
//        System.load("/data/local/tmp/libnative-opencv.so");
    }


    public boolean saveBitmap(Bitmap bitmap, File file) {
        if (bitmap == null)
            return false;
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }


    public final Bitmap getRect(int oriention, Rect v7, int type) {
        Bitmap v0;
        if (Build.VERSION.SDK_INT >= 28) {
            v0 = screenshot(v7, v7.width(), v7.height(), oriention);
        } else {
            if (oriention == 1 || oriention == 3) {
                oriention = oriention == 1 ? 3 : 1;
            }
            μΡ(v7, oriention);
            v0 = screenshot(v7, v7.height(), v7.width(), 0x80000000, 0x7FFFFFFF, false, oriention);
        }
        System.out.println("bmp:" + v0);
        File file = new File(Environment.getExternalStorageDirectory(), "Log/default.jpg");
        if (type == 2) {
            file = new File(Environment.getExternalStorageDirectory(), "Log/weapon.jpg");
        } else if (type == 3) {
            file = new File(Environment.getExternalStorageDirectory(), "Log/accessories1.jpg");
        }
        if (!file.getParentFile().exists()) {
            file.mkdirs();
        }

        if (("huawei".equalsIgnoreCase(Build.BRAND)) && ((Build.MODEL.startsWith("LIO-AN")) || (Build.MODEL.startsWith("LIO-TN")) || (Build.MODEL.startsWith("LIO-AL")) || (Build.MODEL.startsWith("LIO-TL")))) {
            this.Hµ = new Point((v7.width() - v0.getWidth()) / 2, (v7.height() - v0.getHeight()) / 2);
        }
        if (v0 != null)
            saveBitmap(v0, file);
        return v0;
    }

    public final Bitmap getBMP(Rect arg9, int oriention) {
        if (Build.VERSION.SDK_INT >= 28) {
            return screenshot(arg9, arg9.width(), arg9.height(), oriention);
        }
        int v0 = oriention;
        if (v0 == 1 || v0 == 3) {
            v0 = v0 == 1 ? 3 : 1;
        }
        μΡ(arg9, v0);
        return screenshot(arg9, arg9.height(), arg9.width(), 0x80000000, 0x7FFFFFFF, false, v0);
    }

    public Bitmap screenshot(Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform, int rotation) {
        try {
            Class<?> demo = Class.forName("android.view.SurfaceControl");
            Method method = demo.getDeclaredMethod("screenshot", Rect.class, int.class, int.class, int.class, int.class, boolean.class, int.class);
//            method.setAccessible(true);
            return (Bitmap) method.invoke(null, sourceCrop, width, height, minLayer, maxLayer, useIdentityTransform, rotation);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public Bitmap screenshot(Rect sourceCrop, int width, int height, int rotation) {
        try {
            Class<?> demo = Class.forName("android.view.SurfaceControl");
            Method method = demo.getDeclaredMethod("screenshot", Rect.class, int.class, int.class, int.class);
//            method.setAccessible(true);
            return (Bitmap) method.invoke(null, sourceCrop, width, height, rotation);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }

    public void μΡ(Rect arg1, int arg2) {
        if (arg2 == 1 || arg2 == 3) {
            arg2 = arg1.top;
            arg1.top = arg1.left;
            arg1.left = arg2;
            arg2 = arg1.right;
            arg1.right = arg1.bottom;
            arg1.bottom = arg2;
        }
    }
}

2、mat2bitmap bitmap2mat


void BitmapToMat2(JNIEnv *env, jobject &bitmap, Mat &mat, jboolean needUnPremultiplyAlpha) {
    AndroidBitmapInfo info;
    void *pixels = 0;
    Mat &dst = mat;

    try {
        CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0);
        CV_Assert(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ||
                  info.format == ANDROID_BITMAP_FORMAT_RGB_565);
        CV_Assert(AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0);
        CV_Assert(pixels);
        dst.create(info.height, info.width, CV_8UC4);
        if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {

            Mat tmp(info.height, info.width, CV_8UC4, pixels);
            if (needUnPremultiplyAlpha) cvtColor(tmp, dst, COLOR_mRGBA2RGBA);
            else tmp.copyTo(dst);
        } else {
            // info.format == ANDROID_BITMAP_FORMAT_RGB_565

            Mat tmp(info.height, info.width, CV_8UC2, pixels);
            cvtColor(tmp, dst, COLOR_BGR5652RGBA);
        }
        AndroidBitmap_unlockPixels(env, bitmap);
        return;
    } catch (const cv::Exception &e) {
        AndroidBitmap_unlockPixels(env, bitmap);

        jclass je = env->FindClass("org/opencv/core/CvException");
        if (!je) je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, e.what());
        return;
    } catch (...) {
        AndroidBitmap_unlockPixels(env, bitmap);

        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "Unknown exception in JNI code {nBitmapToMat}");
        return;
    }
}

void BitmapToMat(JNIEnv *env, jobject &bitmap, Mat &mat) {
    BitmapToMat2(env, bitmap, mat, false);
}

void MatToBitmap2
        (JNIEnv *env, Mat &mat, jobject &bitmap, jboolean needPremultiplyAlpha) {
    AndroidBitmapInfo info;
    void *pixels = 0;
    Mat &src = mat;

    try {

        CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0);
        CV_Assert(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ||
                  info.format == ANDROID_BITMAP_FORMAT_RGB_565);
        CV_Assert(src.dims == 2 && info.height == (uint32_t) src.rows &&
                  info.width == (uint32_t) src.cols);
        CV_Assert(src.type() == CV_8UC1 || src.type() == CV_8UC3 || src.type() == CV_8UC4);
        CV_Assert(AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0);
        CV_Assert(pixels);
        if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
            Mat tmp(info.height, info.width, CV_8UC4, pixels);
            if (src.type() == CV_8UC1) {

                cvtColor(src, tmp, COLOR_GRAY2RGBA);
            } else if (src.type() == CV_8UC3) {

                cvtColor(src, tmp, COLOR_RGB2RGBA);
            } else if (src.type() == CV_8UC4) {

                if (needPremultiplyAlpha)
                    cvtColor(src, tmp, COLOR_RGBA2mRGBA);
                else
                    src.copyTo(tmp);
            }
        } else {
            // info.format == ANDROID_BITMAP_FORMAT_RGB_565
            Mat tmp(info.height, info.width, CV_8UC2, pixels);
            if (src.type() == CV_8UC1) {

                cvtColor(src, tmp, COLOR_GRAY2BGR565);
            } else if (src.type() == CV_8UC3) {

                cvtColor(src, tmp, COLOR_RGB2BGR565);
            } else if (src.type() == CV_8UC4) {

                cvtColor(src, tmp, COLOR_RGBA2BGR565);
            }
        }
        AndroidBitmap_unlockPixels(env, bitmap);
        return;
    } catch (const cv::Exception &e) {
        AndroidBitmap_unlockPixels(env, bitmap);

        jclass je = env->FindClass("org/opencv/core/CvException");
        if (!je) je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, e.what());
        return;
    } catch (...) {
        AndroidBitmap_unlockPixels(env, bitmap);

        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "Unknown exception in JNI code {nMatToBitmap}");
        return;
    }
}

void MatToBitmap(JNIEnv *env, Mat &mat, jobject &bitmap) {
    MatToBitmap2(env, mat, bitmap, false);
}

选用Android sdk 环境,在/data/local/temp/ 启动会爆出AndroidBitmap_lockPixels的异常

3、灰度化,二值化,轮廓

       cvtColor(temp, gray, COLOR_RGB2GRAY);
        threshold(gray, gray, 55, 255, THRESH_BINARY);
//      Canny(gray, gray, 45, 75);//轮廓
        std::vector<std::vector<Point>> vContours;
        findContours(gray, vContours, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
        std::vector<Rect> rects;

4、感知hash 算法比较图片
经过3的处理

//差值感知算法
long dHash(Mat srcMat, bool isGray) {
    Mat dstMat;
    resize(srcMat, dstMat, Size(8, 8), 0, 0, INTER_CUBIC);
    if (!isGray)
        cvtColor(dstMat, dstMat, COLOR_BGR2GRAY);

    long hash_str = 0;
//每行前一个像素大于后一个像素为1,相反为0,生成哈希
    for (int i = 0; i < 8; i++) {
        uchar *data1 = dstMat.ptr<uchar>(i);
        for (int j = 0; j < 8; j++) {
            if (data1[j] > data1[j + 1]) {
                hash_str ++;
            }
        }
    }

    return hash_str;
}

//平均值hash
long aHash(Mat srcMat, bool isGray) {
    Mat dstMat;
    resize(srcMat, dstMat, Size(8, 8), 0, 0, INTER_CUBIC);
    if (!isGray)
        cvtColor(dstMat, dstMat, COLOR_BGR2GRAY);

    int iAvg = 0;
    int arr[64];
    for (int i = 0; i < 8; i++) {
        uchar *data1 = dstMat.ptr<uchar>(i);
        int tmp = i * 8;
        for (int j = 0; j < 8; j++) {
            int tmp1 = tmp + j;
            arr[tmp1] = data1[j] / 4 * 4;
            iAvg += arr[tmp1];
        }
    }
    iAvg /= 64;

    int p = 1;
    long value = 0;
    for (int i = 0; i < 64; i++) {
        p *= 2;
        if (arr[i] >= iAvg) {
            value += p;
        }
    }
    return value;
}

相关文章

网友评论

      本文标题:Android高级 opencv

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