您的位置:首页 > 移动开发 > Objective-C

android studio + opencv开发,objectMatch摄像头实时处理

2015-11-14 10:01 766 查看
又玩了一遍android studio + opencv开发,每次都配置环境很复杂,这次记录在案,以后就不用网上搜了。

搞了老半天,原来是onCreate里面不能定义Mat
m = new Mat() 傻逼了!

Recommended steps for using OpenCV in Android Studio with OpenCV manager.

Unzip OpenCV Android sdk downloaded from OpenCV.org(3)
From
File
-> Import Module
, choose
sdk/java
folder
in the unzipped opencv archive.
Update
build.gradle
under
imported OpenCV module to update 4 fields to match your project's
build.gradle
a)
compileSdkVersion b) buildToolsVersion c) minSdkVersion and 4) targetSdkVersion.
Add module dependency by
Application
-> Module Settings
, and select the
Dependencies
tab.
Click
+
icon at bottom(or right),
choose
Module Dependency
and select
the imported OpenCV module.

As the final step, in your Activity class, add snippet below.
public class SampleJava extends Activity  {

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch(status) {
case LoaderCallbackInterface.SUCCESS:
Log.i(TAG,"OpenCV Manager Connected");
//from now onwards, you can use OpenCV API
Mat m = new Mat(5, 10, CvType.CV_8UC1, new Scalar(0));
break;
case LoaderCallbackInterface.INIT_FAILED:
Log.i(TAG,"Init Failed");
break;
case LoaderCallbackInterface.INSTALL_CANCELED:
Log.i(TAG,"Install Cancelled");
break;
case LoaderCallbackInterface.INCOMPATIBLE_MANAGER_VERSION:
Log.i(TAG,"Incompatible Version");
break;
case LoaderCallbackInterface.MARKET_ERROR:
Log.i(TAG,"Market Error");
break;
default:
Log.i(TAG,"OpenCV Manager Install");
super.onManagerConnected(status);
break;
}
}
};

@Override
protected void onResume() {
super.onResume();
//initialize OpenCV manager
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_9, this, mLoaderCallback);
}
}


Note: You could only make OpenCV calls after you receive success callback on
onManagerConnected
method.
During run, you will be prompted for installation of OpenCV manager from play store, if it is not already installed. During development, if you don't have access to play store or is on emualtor, use appropriate OpenCV manager apk present in
apk
folder
under downloaded OpenCV sdk archive .

Pros

Apk size reduction by around 40 MB ( consider upgrades too ).
OpenCV manager installs optimized binaries for your hardware which could help speed.
Upgrades to OpenCV manager might save your app from bugs in OpenCV.
Different apps could share same OpenCV library.

Cons

End user experience - might not like a install prompt from with your application.

在android平台上实现objectMatch,实时的识别,提取摄像头的程序参考http://blog.csdn.net/nimeghbia/article/details/49421371

package com.example.wan.trycamerasurf;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.calib3d.Calib3d;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener;
import org.opencv.android.JavaCameraView;
import org.opencv.core.MatOfDMatch;
import org.opencv.core.MatOfKeyPoint;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.features2d.DescriptorExtractor;
import org.opencv.features2d.DescriptorMatcher;
import org.opencv.features2d.FeatureDetector;
import org.opencv.features2d.Features2d;
import org.opencv.highgui.Highgui;

import android.os.Bundle;
import android.app.Activity;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity implements CameraBridgeViewBase.CvCameraViewListener2, View.OnTouchListener{

private static final String  TAG = "MainActivity";
private CameraBridgeViewBase mOpenCvCameraView;
RunSURF runSURF = new RunSURF();

private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");

/* Now enable camera view to start receiving frames */
mOpenCvCameraView.setOnTouchListener(MainActivity.this);
mOpenCvCameraView.enableView();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Log.d(TAG, "Creating and setting view");
mOpenCvCameraView = (CameraBridgeViewBase) new JavaCameraView(this,-1);
setContentView(mOpenCvCameraView);
mOpenCvCameraView.setCvCameraViewListener(this);
//        runSURF = new RunSURF();
}
@Override
public void onResume()
{
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_11, this, mLoaderCallback);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

return super.onOptionsItemSelected(item);
}

@Override
public void onCameraViewStarted(int width, int height) {

}

@Override
public void onCameraViewStopped() {

}
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
Mat img_object = Highgui.imread(Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/lena2.png");
Mat img_scene_R = inputFrame.rgba();
Mat img_scene = inputFrame.gray();
Mat outMat = new Mat();
outMat = img_scene;
//        System.out.println(img_scene);
FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
MatOfKeyPoint keypoints_object = new MatOfKeyPoint();
MatOfKeyPoint keypoints_scene = new MatOfKeyPoint();
detector.detect(img_object, keypoints_object);
detector.detect(img_scene, keypoints_scene);
DescriptorExtractor extractor = DescriptorExtractor.create(DescriptorExtractor.ORB);
Mat descriptors_object = new Mat();
Mat descriptors_scene = new Mat();
extractor.compute(img_object, keypoints_object, descriptors_object);
extractor.compute(img_scene, keypoints_scene, descriptors_scene);
Mat imgKepoint = new Mat();
Features2d.drawKeypoints(img_object, keypoints_object, imgKepoint);
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE);
MatOfDMatch matches = new MatOfDMatch();
matcher.match(descriptors_object, descriptors_scene, matches);
//        Mat img_matches = new Mat();
//        Features2d.drawMatches(img_object, keypoints_object, img_scene, keypoints_scene, matches, img_matches);
double max_dist = 0;
double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for (int i = 0; i < descriptors_object.rows(); i++) {
double dist = matches.toArray()[i].distance;
if (dist < min_dist) min_dist = dist;
if (dist > max_dist) max_dist = dist;
}
System.out.println("-- Max dist : " + max_dist);
System.out.println("-- Min dist : " + min_dist);
//-- Draw only "good" matches (i.e. whose distance is less than 3*min_dist )
MatOfDMatch good_matches = new MatOfDMatch();
for (int i = 0; i < descriptors_object.rows(); i++) {
if (matches.toArray()[i].distance < 3 * min_dist) {
//System.out.println(matches.toArray()[i].distance);
good_matches.push_back(matches.row(i));
}
}
MatOfPoint2f obj = new MatOfPoint2f();
MatOfPoint2f scene = new MatOfPoint2f();
List<Point> objp = new ArrayList<>();
List<Point> scenep = new ArrayList<>();
for (int i = 0; i < good_matches.rows(); i++) {
//-- Get the keypoints from the good matches
objp.add(keypoints_object.toArray()[good_matches.toArray()[i].queryIdx].pt);
scenep.add(keypoints_scene.toArray()[good_matches.toArray()[i].trainIdx].pt);
}
obj.fromList(objp);
scene.fromList(scenep);
Mat H = Calib3d.findHomography(obj, scene, Calib3d.RANSAC, Calib3d.CALIB_CB_ADAPTIVE_THRESH);
System.out.println(H);
//        Mat H = Calib3d.findHomography(obj,scene);
//        Calib3d.findHomography(obj, scene);
//-- Get the corners from the image_1 ( the object to be "detected" )
MatOfPoint2f obj_corners = new MatOfPoint2f();
List<Point> obj_cornersp = new ArrayList<>();
Point point1 = new Point(0, 0);
obj_cornersp.add(point1);
Point point2 = new Point(img_object.cols(), 0);
obj_cornersp.add(point2);
Point point3 = new Point(img_object.cols(), img_object.rows());
obj_cornersp.add(point3);
Point point4 = new Point(0, img_object.rows());
obj_cornersp.add(point4);
obj_corners.fromList(obj_cornersp);
//        System.out.println(obj_corners.toList());
MatOfPoint2f scene_corners = new MatOfPoint2f();
Core.perspectiveTransform(obj_corners, scene_corners, H);
//        System.out.println(scene_corners.toList());
//-- Draw lines between the corners (the mapped object in the scene - image_2 )
Scalar scalar = new Scalar(0, 255, 0);
Point pp1 = new Point(scene_corners.toArray()[0].x , scene_corners.toArray()[0].y);
Point pp2 = new Point(scene_corners.toArray()[1].x , scene_corners.toArray()[1].y);
Point pp3 = new Point(scene_corners.toArray()[2].x , scene_corners.toArray()[2].y);
Point pp4 = new Point(scene_corners.toArray()[3].x , scene_corners.toArray()[3].y);
//        System.out.println(pp1);
//        System.out.println(pp2);
//        System.out.println(pp3);
//        System.out.println(pp4);
Core.line(outMat, pp1, pp2, scalar, 4);
Core.line(outMat, pp2, pp3, scalar, 4);
Core.line(outMat, pp3, pp4, scalar, 4);
Core.line(outMat, pp4, pp1, scalar, 4);
//        return runSURF.run(inputFrame.gray());
//        if (matches.rows()>0)
//            return img_matches;
//        else
//            return img_scene;
return outMat;
}

@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
}

即把上周的java上实现的转移到android端,能实时的在摄像头画面识别特定图片,目前程序中只支持lena2这幅。。。
java程序:/article/10908293.html
问题1:用另一个java类写匹配程序,在主activity中调用会报错,显示缓存溢出,所以只能选择把程序写在onCameraFrame里面,
问题2:不程序执行速度是个大问题,虽然用的ORB算法,但几秒钟才能匹配显示一次,卡顿严重。
问题3:图片显示只能是黑白的。。。
未来:能识别多张图片且提高速度。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: