Android Jni OpenCV-基于ORB算法特征点匹配

一,java代码,收集Bitmap 信息
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private Button btnProc;
private ImageView imageView;
private Bitmap bmp;

// 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);

    // Example of a call to a native method
    btnProc = (Button) findViewById(R.id.btn_gray_process);
    imageView = (ImageView) findViewById(R.id.image_view);

    bmp = BitmapFactory.decodeResource(getResources(), R.drawable.test7);
    imageView.setImageBitmap(bmp);
    btnProc.setOnClickListener(this);
}

/**
 * A native method that is implemented by the 'native-lib' native library,
 * which is packaged with this application.
 */
public static native int[] grayProc(int[] pixels, int w, int h);


@Override
public void onClick(View view) {

    int w = bmp.getWidth();
    int h = bmp.getHeight();
    int[] pixels = new int[w*h];
    bmp.getPixels(pixels, 0, w, 0, 0, w, h);

    long startTime = System.currentTimeMillis();
    int[] resultInt = grayProc(pixels, w, h);
    long endTime = System.currentTimeMillis();

    Log.e("JNITime",""+(endTime-startTime));
    Bitmap resultImg = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);

    //(@ColorInt int[] pixels, int offset, int stride,int x, int y, int width, int height)
    resultImg.setPixels(resultInt, 0, w, 0, 0, w, h);
    imageView.setImageBitmap(resultImg);

}

}

二,jni实现

这里写图片描述

using namespace std;
using namespace cv;

void printMAtMessage(Mat &mat);

extern “C”
JNIEXPORT jintArray JNICALL
Java_com_example_dgxq008_opencv_1readpixel_MainActivity_grayProc(JNIEnv *env, jclass type
, jintArray pixels_
, jint w
, jint h) {

jint* pixels = env->GetIntArrayElements(pixels_, NULL);
if (pixels==NULL){
    return 0;
}

//图片一进来时是ARGB  通过mat转换BGRA
Mat img(h,w,CV_8UC4,(uchar *)pixels);  //pixels 操作的是同一份数据

Mat temp;
//转化为单通道灰度图,并打印信息
cvtColor(img,temp,COLOR_RGBA2GRAY);

vector<KeyPoint> v;
v.clear();

/*
 * ORB算法
 * 使用默认构造参数
 *
 *  nfeatures - 最多提取的特征点的数量;
 *  scaleFactor - 金字塔图像之间的尺度参数,类似于SIFT中的kk;
 *  nlevels – 高斯金字塔的层数;
 *  edgeThreshold – 边缘阈值,这个值主要是根据后面的patchSize来定的,靠近边缘
 *  edgeThreshold以内的像素是不检测特征点的。        
 * firstLevel - 看过SIFT都知道,我们可以指定第一层的索引值,这里默认为0。
 * 
 * scoreType - 用于对特征点进行排序的算法,你可以选择HARRIS_SCORE,也可以选择
 * FAST_SCORE,但是它也只是比前者快一点点而已。
 * 
 * patchSize – 用于计算BIREF描述子的特征点邻域大小。
 * */

Ptr<ORB> orb = ORB::create();

//开始识别
orb->detect(temp, v, cv::Mat());

for (int i = 0; i < v.size(); ++i) {
    const KeyPoint& kp = v[i];

    /*
     * img为源图像指针
     * center为画圆的圆心坐标
     * radius为圆的半径
     * color为设定圆的颜色,规则根据B(蓝)G(绿)R(红)
     * thickness 如果是正数,表示组成圆的线条的粗细程度。否则,表示圆是否被填充
     * line_type 线条的类型。默认是8
     * shift 圆心坐标点和半径值的小数点位数
     * */
    circle(img, Point(kp.pt.x, kp.pt.y), 5, Scalar(255,10,10,255));
}

printMAtMessage(img);

//对应数据指针
int size = w*h;
jintArray result = env->NewIntArray(size);
env->SetIntArrayRegion(result,0,size,pixels);

env->ReleaseIntArrayElements(pixels_, pixels, 0);

return result;

}

void printMAtMessage(Mat &mat) {
LOGD(“***************************Mat信息开始************************”);
LOGD(“mat.rows %d”,mat.rows);
LOGD(“mat.cols %d”,mat.cols);
LOGD(“mat.total %d”,mat.total());
LOGD(“mat.channels %d”,mat.channels());
LOGD(“mat.depth %d”,mat.depth());
LOGD(“mat.type %d”,mat.type());
LOGD(“mat.flags %d”,mat.flags);
LOGD(“mat.elemSize %d”,mat.elemSize());
LOGD(“mat.elemSize1 %d”,mat.elemSize1());
LOGD(“***************************Mat信息结束************************”);
}

三,效果图

这里写图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android中使用JNI调用OpenCV库来实现摄像头功能是可行的。以下是调用摄像头的简单步骤: 首先,你需要在Android项目中集成OpenCV库。可以通过将OpenCV库添加到Gradle依赖项或手动导入库文件来完成。 其次,创建一个JNI接口,将Java代码与C/C++代码进行绑定。JNI接口允许在Java和C/C++之间进行双向通信。 然后,在C/C++代码中编写与摄像头相关的功能。可以使用OpenCV提供的函数和类来处理视频流。例如,你可以使用VideoCapture类打开摄像头并获取图像帧。 接下来,在JNI接口中实现调用摄像头的功能。通过JNI接口,将Java代码的请求传递给C/C++函数来执行摄像头操作。你可以设置一个循环,不断从摄像头读取图像帧并进行处理。 最后,在Java代码中调用JNI接口中的方法来启动摄像头。可以使用SurfaceView来显示摄像头捕获的图像。你可以使用Camera类来控制摄像头的预览以及其他设置。 需要注意的是,在JNI和C/C++代码中处理摄像头操作时,要遵循正确的线程管理和图像处理技术,以确保流畅的手机摄像头应用程序。 总之,通过JNI调用OpenCV库,可以很方便地在Android上实现摄像头功能。项目中要同时涉及Java和C/C++代码,需要进行正确的接口绑定和线程管理。这样,你可以轻松地使用OpenCV函数和类来处理摄像头操作并实现自己的摄像头应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值