openCV ORB 图片特征检测 与 匹配
2019-08-01 本文已影响0人
MrY_124d
视频流匹配
特征检测对比
导入openCVLibrary libray 就不说了
相机返回来的数据流
@Override
public void onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();
mGray = inputFrame.gray();
Mat matLin = mGray.clone();
Core.flip(mGray, matLin, 0);//-1 0 1 //旋转90
Core.transpose(matLin, mGray);// 翻转
orb 的使用
public ImageMatcher() {
orb = ORB.create(2000);
gftt = GFTTDetector.create();
descriptorMatcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
}
摸版图片
public boolean src(Mat scene) {
this.sceneMat = scene;
sceneKeyPoint = new MatOfKeyPoint();
sceneDescriptors = new Mat();
// //发现特征
// gftt.detect(scene,sceneKeyPoint);
// //描述
// orb.compute(scene,sceneKeyPoint,sceneDescriptors);
orb.detectAndCompute(scene, new Mat(), sceneKeyPoint, sceneDescriptors);
return sceneKeyPoint.toArray().length > 8;
}
public void match(Mat objectMat){
try {
long t = System.currentTimeMillis();
MatOfKeyPoint objectKeyPoint = new MatOfKeyPoint();
Mat objectDescriptors = new Mat();
// gftt.detect(objectMat,objectKeyPoint);
// orb.compute(objectMat,objectKeyPoint,objectDescriptors);
orb.detectAndCompute(objectMat, new Mat(), objectKeyPoint, objectDescriptors);
//匹配
List<MatOfDMatch> matches = new ArrayList<>();
descriptorMatcher.knnMatch(sceneDescriptors, objectDescriptors, matches, 2);
// descriptorMatcher.radiusMatch(sceneDescriptors,objectDescriptors,matches,200f);
//帅选
List<MatOfDMatch> goodMatOfDMatch = new ArrayList<>();
List<DMatch> goodMatches = new ArrayList<>();
for (MatOfDMatch match : matches) {
DMatch[] dMatches = match.toArray();
if (dMatches[0].distance < 0.7 * dMatches[1].distance) {
goodMatches.add(dMatches[0]);
goodMatOfDMatch.add(match);
}
}
if (goodMatches.size() > 4) {
List<KeyPoint> sceneKeyPoints = sceneKeyPoint.toList();
List<KeyPoint> objectKeyPoints = objectKeyPoint.toList();
List<Point> objectPoints = new ArrayList<>();
List<Point> scenePoints = new ArrayList<>();
for (DMatch goodMatch : goodMatches) {
scenePoints.add(sceneKeyPoints.get(goodMatch.queryIdx).pt);
objectPoints.add(objectKeyPoints.get(goodMatch.trainIdx).pt);
}
MatOfPoint2f sceMatOfPoint2f = new MatOfPoint2f();
MatOfPoint2f objMatOfPoint2f = new MatOfPoint2f();
sceMatOfPoint2f.fromList(scenePoints);
objMatOfPoint2f.fromList(objectPoints);
//因为需要使用findHomography函数来实现RANSAC算法,对特征点进行筛选
Mat H = Calib3d.findHomography(sceMatOfPoint2f, objMatOfPoint2f, Calib3d.RANSAC, 3);
/**
* 透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。
*/
Mat scene_corners = new Mat(4, 1, CvType.CV_32FC2);
scene_corners.put(0, 0, 0, 0);
scene_corners.put(1, 0, sceneMat.cols(), 0);
scene_corners.put(2, 0, sceneMat.cols(), sceneMat.rows());
scene_corners.put(3, 0, 0, sceneMat.rows());
//使用 perspectiveTransform 将模板图进行透视变以矫正图象得到标准图片
Mat object_corners = new Mat(4, 1, CvType.CV_32FC2);
Core.perspectiveTransform(scene_corners, object_corners, H);
//矩形四个顶点
Point pointA = new Point(object_corners.get(0, 0));
Point pointB = new Point(object_corners.get(1, 0));
Point pointC = new Point(object_corners.get(2, 0));
Point pointD = new Point(object_corners.get(3, 0));
if (listener != null)
listener.onMatcherPoint(pointA, pointB, pointC, pointD);
//将匹配的图像用用四条线框出来
// Imgproc.line(objectMat, pointA, pointB, new Scalar(0, 255, 0), 2);//上 A->B
// Imgproc.line(objectMat, pointB, pointC, new Scalar(0, 255, 0), 2);//右 B->C
// Imgproc.line(objectMat, pointC, pointD, new Scalar(0, 255, 0), 2);//下 C->D
// Imgproc.line(objectMat, pointD, pointA, new Scalar(0, 255, 0), 2);//左 D->A
// Imgproc.rectangle(objectMat, pointA, pointC, new Scalar(0, 255, 0), 2);
// //绘制匹配图
// Bitmap bitmap = Bitmap.createBitmap(objectMat.cols(), objectMat.rows(), Bitmap.Config.ARGB_4444);
// Utils.matToBitmap(objectMat, bitmap);
L.t(t);
} else {
if (listener != null) {
listener.onMatcherLose();
}
}
if (listener != null) {
listener.detect(sceneKeyPoint, objectKeyPoint);
Bitmap bitmap = getDrawMatches2Bitmap(sceneMat, sceneKeyPoint, objectMat, objectKeyPoint, goodMatOfDMatch);
listener.drawMatches2(bitmap);
}
} catch (Exception e) {
//e.printStackTrace();
}
}