В настоящее время я использую OpenCV для сравнения двух изображений, чтобы узнать, похожи они или нет в Android. Я использую ORB Feature Detectors и Descriptor Extractors. Вот что я до сих пор. Я нахожу все ключевые моменты функции в первом изображении, а затем нахожу все ключевые точки функции во втором изображении. Затем я нахожу дескрипторы для этих ключевых точек, а затем выполняю совпадение между двумя изображениями.OpenCV Android: Как нарисовать соответствующие ключевые точки над сравниваемыми изображениями?
private void matchImages() {
Mat refMat = new Mat();
Mat srcMat = new Mat();
Bitmap refBitmap = ((BitmapDrawable) mRefImg.getDrawable()).getBitmap();
Bitmap srcBitmap = ((BitmapDrawable) mSrcImg.getDrawable()).getBitmap();
Utils.bitmapToMat(refBitmap, refMat);
Utils.bitmapToMat(srcBitmap, srcMat);
MatOfDMatch matches = new MatOfDMatch();
MatOfDMatch goodMatches = new MatOfDMatch();
LinkedList<DMatch> listOfGoodMatches = new LinkedList<>();
LinkedList<Point> refObjectList = new LinkedList<>();
LinkedList<Point> srcObjectList = new LinkedList<>();
MatOfKeyPoint refKeypoints = new MatOfKeyPoint();
MatOfKeyPoint srcKeyPoints = new MatOfKeyPoint();
Mat refDescriptors = new Mat();
Mat srcDescriptors = new Mat();
MatOfPoint2f reference = new MatOfPoint2f();
MatOfPoint2f source = new MatOfPoint2f();
FeatureDetector orbFeatureDetector = FeatureDetector.create(FeatureDetector.ORB);
orbFeatureDetector.detect(refMat, refKeypoints);
orbFeatureDetector.detect(srcMat, srcKeyPoints);
DescriptorExtractor descriptorExtractor = DescriptorExtractor.create(DescriptorExtractor.ORB);
descriptorExtractor.compute(refMat, refKeypoints, refDescriptors);
descriptorExtractor.compute(srcMat, srcKeyPoints, srcDescriptors);
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
matcher.match(refDescriptors, srcDescriptors, matches);
double max_dist = 0;
double min_dist = 100;
List<DMatch> matchesList = matches.toList();
for (int i = 0; i < refDescriptors.rows(); i++) {
Double distance = (double) matchesList.get(i).distance;
if (distance < min_dist) min_dist = distance;
if (distance > max_dist) max_dist = distance;
}
for (int i = 0; i < refDescriptors.rows(); i++) {
if (matchesList.get(i).distance < 3 * min_dist) {
listOfGoodMatches.add(matchesList.get(i));
}
}
goodMatches.fromList(listOfGoodMatches);
List<KeyPoint> refObjectListKeypoints = refKeypoints.toList();
List<KeyPoint> srcObjectListKeypoints = srcKeyPoints.toList();
for (int i = 0; i < listOfGoodMatches.size(); i++) {
refObjectList.addLast(refObjectListKeypoints.get(listOfGoodMatches.get(i).queryIdx).pt);
srcObjectList.addLast(srcObjectListKeypoints.get(listOfGoodMatches.get(i).trainIdx).pt);
}
reference.fromList(refObjectList);
source.fromList(srcObjectList);
String result;
if(listOfGoodMatches.size() > MIN_MATCH_THRESHOLD && listOfGoodMatches.size() < MAX_MATCH_THRESHOLD) {
result = "They MATCH!";
} else {
result = "They DON'T match!";
}
AlertDialog alert = new AlertDialog.Builder(this)
.setMessage(result)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// close
}
}).create();
alert.show();
Mat outputImage = new Mat();
Bitmap comboBmp = combineImages(refBitmap, srcBitmap);
Utils.bitmapToMat(comboBmp, outputImage);
Features2d.drawMatches(refMat, refKeypoints, srcMat, srcKeyPoints, goodMatches, outputImage);
Bitmap bitmap = Bitmap.createBitmap(outputImage.cols(), outputImage.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(outputImage, bitmap);
mRefImg.setImageBitmap(comboBmp);
mRefImg.invalidate();
mSrcImg.setImageBitmap(bitmap);
mSrcImg.invalidate();
}
Это просто приложение «песочницы», которое я создал, чтобы проверить и поиграть с этой библиотекой. В результате приведенного выше кода дает следующее если сравнить два изображения:
Как вы можете видеть, фон из матчей черный. Как я могу нарисовать эти соответствия по изображению слева? Пример того, как бы хотелось, чтобы мой результат выглядел вот так: https://stackoverflow.com/a/14909358/3779845