opencv java 特征提取_OPENCV特征点java提取与匹配与比较

opencv的features2d包中提供了surf,sift和orb等特征点算法,用于图像查找图像对象,搜索对象,分析对象,识别对象,合成全景等场合。

研究这些算法的原理和实现,是图像识别基础,OPENCV库使用2.413

通过一些代码研究三种特征点算法,我有意把原始图像转为灰度并放置90与照处中人物比较,以研究三种算法对人脸识别的优点和局限。辅助使用了人脸查找获取待查找图像中人脸子矩阵。上代码。

import java.util.ArrayList;

import java.util.LinkedList;

import java.util.List;

import org.opencv.core.Core;

import org.opencv.core.Mat;

import org.opencv.core.MatOfDMatch;

import org.opencv.core.MatOfKeyPoint;

import org.opencv.core.MatOfRect;

import org.opencv.core.Size;

import org.opencv.features2d.DMatch;

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 org.opencv.imgproc.Imgproc;

import org.opencv.objdetect.CascadeClassifier;

public class ExtractSIFT2 {

public static void main(String[] args) {

System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

Mat src = Highgui.imread("E:/work/qqq/Y9.jpg");

Mat dst = Highgui.imread("E:/work/qqq/psb.jpg");

MatOfRect mr = getFace(dst);

Mat sub = dst.submat(mr.toArray()[0]);

Highgui.imwrite("E:/work/qqq/Y4.jpg", FeatureSurfBruteforce(src.t(), sub));

Highgui.imwrite("E:/work/qqq/Y5.jpg", FeatureSiftLannbased(src.t(), sub));

Highgui.imwrite("E:/work/qqq/Y6.jpg", FeatureOrbLannbased(src.t(), sub));

}

public static Mat FeatureSurfBruteforce(Mat src, Mat dst){

FeatureDetector fd = FeatureDetector.create(FeatureDetector.SURF);

DescriptorExtractor de = DescriptorExtractor.create(DescriptorExtractor.SURF);

//DescriptorMatcher Matcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);

DescriptorMatcher Matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_L1);

MatOfKeyPoint mkp = new MatOfKeyPoint();

fd.detect(src, mkp);

Mat desc = new Mat();

de.compute(src, mkp, desc);

Features2d.drawKeypoints(src, mkp, src);

MatOfKeyPoint mkp2 = new MatOfKeyPoint();

fd.detect(dst, mkp2);

Mat desc2 = new Mat();

de.compute(dst, mkp2, desc2);

Features2d.drawKeypoints(dst, mkp2, dst);

// Matching features

MatOfDMatch Matches = new MatOfDMatch();

Matcher.match(desc, desc2, Matches);

double maxDist = Double.MIN_VALUE;

double minDist = Double.MAX_VALUE;

DMatch[] mats = Matches.toArray();

for (int i = 0; i < mats.length; i++) {

double dist = mats[i].distance;

if (dist < minDist) {

minDist = dist;

}

if (dist > maxDist) {

maxDist = dist;

}

}

System.out.println("Min Distance:" + minDist);

System.out.println("Max Distance:" + maxDist);

List goodMatch = new LinkedList<>();

for (int i = 0; i < mats.length; i++) {

double dist = mats[i].distance;

if (dist < 3 * minDist && dist < 0.2f) {

goodMatch.add(mats[i]);

}

}

Matches.fromList(goodMatch);

// Show result

Mat OutImage = new Mat();

Features2d.drawMatches(src, mkp, dst, mkp2, Matches, OutImage);

return OutImage;

}

public static Mat FeatureSiftLannbased(Mat src, Mat dst){

FeatureDetector fd = FeatureDetector.create(FeatureDetector.SIFT);

DescriptorExtractor de = DescriptorExtractor.create(DescriptorExtractor.SIFT);

DescriptorMatcher Matcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);

MatOfKeyPoint mkp = new MatOfKeyPoint();

fd.detect(src, mkp);

Mat desc = new Mat();

de.compute(src, mkp, desc);

Features2d.drawKeypoints(src, mkp, src);

MatOfKeyPoint mkp2 = new MatOfKeyPoint();

fd.detect(dst, mkp2);

Mat desc2 = new Mat();

de.compute(dst, mkp2, desc2);

Features2d.drawKeypoints(dst, mkp2, dst);

// Matching features

MatOfDMatch Matches = new MatOfDMatch();

Matcher.match(desc, desc2, Matches);

List l = Matches.toList();

List goodMatch = new ArrayList();

for (int i = 0; i < l.size(); i++) {

DMatch dmatch = l.get(i);

if (Math.abs(dmatch.queryIdx - dmatch.trainIdx) < 10f) {

goodMatch.add(dmatch);

}

}

Matches.fromList(goodMatch);

// Show result

Mat OutImage = new Mat();

Features2d.drawMatches(src, mkp, dst, mkp2, Matches, OutImage);

return OutImage;

}

public static Mat FeatureOrbLannbased(Mat src, Mat dst){

FeatureDetector fd = FeatureDetector.create(FeatureDetector.ORB);

DescriptorExtractor de = DescriptorExtractor.create(DescriptorExtractor.ORB);

DescriptorMatcher Matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_L1);

MatOfKeyPoint mkp = new MatOfKeyPoint();

fd.detect(src, mkp);

Mat desc = new Mat();

de.compute(src, mkp, desc);

Features2d.drawKeypoints(src, mkp, src);

MatOfKeyPoint mkp2 = new MatOfKeyPoint();

fd.detect(dst, mkp2);

Mat desc2 = new Mat();

de.compute(dst, mkp2, desc2);

Features2d.drawKeypoints(dst, mkp2, dst);

// Matching features

MatOfDMatch Matches = new MatOfDMatch();

Matcher.match(desc, desc2, Matches);

double maxDist = Double.MIN_VALUE;

double minDist = Double.MAX_VALUE;

DMatch[] mats = Matches.toArray();

for (int i = 0; i < mats.length; i++) {

double dist = mats[i].distance;

if (dist < minDist) {

minDist = dist;

}

if (dist > maxDist) {

maxDist = dist;

}

}

System.out.println("Min Distance:" + minDist);

System.out.println("Max Distance:" + maxDist);

List goodMatch = new LinkedList<>();

for (int i = 0; i < mats.length; i++) {

double dist = mats[i].distance;

if (dist < 3 * minDist && dist < 0.2f) {

goodMatch.add(mats[i]);

}

}

Matches.fromList(goodMatch);

// Show result

Mat OutImage = new Mat();

Features2d.drawMatches(src, mkp, dst, mkp2, Matches, OutImage);

//Highgui.imwrite("E:/work/qqq/Y4.jpg", OutImage);

return OutImage;

}

public static MatOfRect getFace(Mat src) {

Mat result = src.clone();

if (src.cols() > 1000 || src.rows() > 1000) {

Imgproc.resize(src, result, new Size(src.cols() / 3, src.rows() / 3));

}

CascadeClassifier faceDetector = new CascadeClassifier("./resource/haarcascade_frontalface_alt2.xml");

MatOfRect objDetections = new MatOfRect();

faceDetector.detectMultiScale(result, objDetections);

return objDetections;

}

}

人脸灰度图,待处理的图片和处理后三种方法对比,做了一些简单的取优。结果来看,orb算法似乎优于其他两种。

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

参考:

http://blog.csdn.net/liufanghuangdi/article/details/52957094?locationNum=2&fps=1

http://blog.csdn.net/shuzhe66/article/details/40824883

你可能感兴趣的:(opencv,java,特征提取)