Android和Java通性之OpenCV(角点检测综合)
OpenCV大部分代码是用C写的,包括算法,只有部分是用Java写的,也是一个跨平台的计算机视觉库。
在这篇博客主要是看Java实现的那部分,如果要实现比较特殊的,或者自己实现算法,就得用JNI Java调用C来实现。
当然大部分Java实现的算法也是通过调用C实现的,但是大部分C没有做Java封装。
Android OpenCV项目结构:
以下是代码:
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;
public class BaseFeatrue2DActivity extends AppCompatActivity {
private ImageView baseprocessView=null;
private ImageView processView1=null;
private ImageView processView2=null;
Bitmap baseBitmap=null;
Mat baseMat=null;
Bitmap processBitmap =null;
Mat processMat =null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.base_feature2d);
baseprocessView=(ImageView)findViewById(R.id.baseprocessView);
processView1=(ImageView)findViewById(R.id.processView1);
processView2=(ImageView)findViewById(R.id.processView2);
/**
* 原图
*/
baseBitmap= BitmapFactory.decodeResource(this.getResources(),R.mipmap.test);
baseprocessView.setImageBitmap(baseBitmap);
/**
* Harris 角点检测子
*/
baseBitmap= BitmapFactory.decodeResource(this.getResources(),R.mipmap.test);
baseMat=new Mat(baseBitmap.getWidth(),baseBitmap.getHeight(), CvType.CV_8UC4);
processBitmap = Bitmap.createBitmap(baseBitmap.getWidth(), baseBitmap.getHeight(), Bitmap.Config.RGB_565);
processMat =new Mat(processBitmap.getWidth(), processBitmap.getHeight(), CvType.CV_8UC4);
Mat cornerHarris=new Mat(processBitmap.getWidth(), processBitmap.getHeight(), CvType.CV_8UC4);
Utils.bitmapToMat(baseBitmap,baseMat,true);
Imgproc.cvtColor(baseMat, processMat,Imgproc.COLOR_BGR2GRAY);
Imgproc.cornerHarris(processMat,cornerHarris,2,3,0.04, 1);
Core.normalize(cornerHarris,cornerHarris,0,225,Core.NORM_MINMAX,CvType.CV_32FC1,new Mat());
Core.convertScaleAbs(cornerHarris,cornerHarris);
Mat resultMat=baseMat.clone();
for( int j = 0; j < resultMat.rows() ; j++ ) {
for( int i = 0; i < resultMat.cols(); i++ ) {
if((cornerHarris.get(j,i).clone()[0]>200)){
Imgproc.circle(resultMat, new Point(i,j), 1, new Scalar(0,0,255),Imgproc.FILLED);
}
}
}
Utils.matToBitmap(resultMat, processBitmap,true);
processView1.setImageBitmap(processBitmap);
baseMat.release();
processMat.release();
baseBitmap.recycle();
/**
* Shi-Tomasi 角点检测子
*/
baseBitmap= BitmapFactory.decodeResource(this.getResources(),R.mipmap.test);
baseMat=new Mat(baseBitmap.getWidth(),baseBitmap.getHeight(), CvType.CV_8UC4);
processBitmap = Bitmap.createBitmap(baseBitmap.getWidth(), baseBitmap.getHeight(), Bitmap.Config.RGB_565);
processMat =new Mat(processBitmap.getWidth(), processBitmap.getHeight(), CvType.CV_8UC4);
Utils.bitmapToMat(baseBitmap,baseMat,true);
Imgproc.cvtColor(baseMat, processMat,Imgproc.COLOR_BGR2GRAY,4);
MatOfPoint corners=new MatOfPoint();
Imgproc.goodFeaturesToTrack(processMat, corners, 200, 0.01, 10, new Mat(), 3, 5, false, 0.04);
int[] cornersData = new int[(int) (corners.total() * corners.channels())];
corners.get(0, 0, cornersData);
for (int i = 0; i < corners.rows(); i++) {
Imgproc.circle(baseMat, new Point(cornersData[i * 2], cornersData[i * 2 + 1]), 3, new Scalar(0, 0,255), Imgproc.FILLED);
}
Utils.matToBitmap(baseMat, processBitmap,true);
processView2.setImageBitmap(processBitmap);
baseMat.release();
processMat.release();
baseBitmap.recycle();
}
}
结果图: