Хорошо, так что я студент университета, занятый выполнением годового проекта.По сути, я пытаюсь разрешить пользователю иметь количество «х» изображений, которые они сохранят на своем устройстве Android.После сохранения этих изображений пользователь может «сканировать» с помощью камеры, и изображение с камеры в реальном времени будет сравниваться с сохраненными изображениями, и будет отображаться сообщение «найдено совпадений» или что-то в этом духе.
Iполучили соответствие, работающее для 1 изображения и только 1 изображения.Я не могу понять, как сравнить с более чем 1 изображение.Я пытался найти решения, но большинство из них связаны с C ++ или Python, что мне не очень помогает, поскольку я не могу понять, как это сделать в Android Studio.Любая помощь будет принята с благодарностью.
Изображение здесь Текущая система
PS: Это университетский проект для доказательства концепции, мое соответствие внизу, кажется, работает длято, что я проверил, поэтому я не слишком беспокоюсь о повышении точности на этом этапе, позволяя сравнивать только несколько изображений.
public class ScanTattooActivity extends Activity implements CameraBridgeViewBase.CvCameraViewListener2 {
private static final String TAG = "Scan Tattoo::Activity";
private int w, h;
private CameraBridgeViewBase mOpenCvCameraView;
TextView tvName;
Scalar RED = new Scalar(255, 0, 0);
Scalar GREEN = new Scalar(0, 255, 0);
FeatureDetector detector;
DescriptorExtractor descriptor;
DescriptorMatcher matcher;
Mat descriptors2,descriptors1;
Mat img1;
MatOfKeyPoint keypoints1,keypoints2;
int match_count = 0;
static {
if (!OpenCVLoader.initDebug())
Log.d("ERROR", "Unable to load OpenCV");
else
Log.d("SUCCESS", "OpenCV loaded");
}
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS: {
Log.i(TAG, "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
try {
initializeOpenCVDependencies();
} catch (IOException e) {
e.printStackTrace();
}
}
break;
default: {
super.onManagerConnected(status);
}
break;
}
}
};
private void initializeOpenCVDependencies() throws IOException {
mOpenCvCameraView.enableView();
detector = FeatureDetector.create(FeatureDetector.ORB);
descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB);
matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
img1 = new Mat();
AssetManager assetManager = getAssets();
InputStream istr = assetManager.open("ajpeg2.jpg");
Bitmap bitmap = BitmapFactory.decodeStream(istr);
Utils.bitmapToMat(bitmap, img1);
Imgproc.cvtColor(img1, img1, Imgproc.COLOR_RGB2GRAY);
img1.convertTo(img1, 0); //converting the image to match with the type of the cameras image
descriptors1 = new Mat();
keypoints1 = new MatOfKeyPoint();
detector.detect(img1, keypoints1);
descriptor.compute(img1, keypoints1, descriptors1);
}
public ScanTattooActivity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_scan_tattoo);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.scantattoo_activity_java_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
//tvName = (TextView) findViewById(R.id.text1);
}
@Override
public void onPause() {
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
public void onResume() {
super.onResume();
if (!OpenCVLoader.initDebug()) {
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
} else {
Log.d(TAG, "OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
public void onCameraViewStarted(int width, int height) {
w = width;
h = height;
}
public void onCameraViewStopped() {
}
public Mat recognize(Mat aInputFrame) {
Imgproc.cvtColor(aInputFrame, aInputFrame, Imgproc.COLOR_RGB2GRAY);
descriptors2 = new Mat();
keypoints2 = new MatOfKeyPoint();
detector.detect(aInputFrame, keypoints2);
descriptor.compute(aInputFrame, keypoints2, descriptors2);
int count = 0;
// Matching
MatOfDMatch matches = new MatOfDMatch();
if (img1.type() == aInputFrame.type()) {
matcher.match(descriptors1, descriptors2, matches);
} else {
return aInputFrame;
}
List<DMatch> matchesList = matches.toList();
Double max_dist = 0.0;
Double min_dist = 100.0;
for (int i = 0; i < matchesList.size(); i++) {
Double dist = (double) matchesList.get(i).distance;
if (dist < min_dist)
min_dist = dist;
if (dist > max_dist)
max_dist = dist;
}
double goodMatchesSum = 0;
LinkedList<DMatch> good_matches = new LinkedList<DMatch>();
for (int i = 0; i < matchesList.size(); i++) {
if (matchesList.get(i).distance <= (1.5 * min_dist))
good_matches.addLast(matchesList.get(i));
goodMatchesSum += matchesList.get(i).distance;
count ++;
}
MatOfDMatch goodMatches = new MatOfDMatch();
goodMatches.fromList(good_matches);
Mat outputImg = new Mat();
MatOfByte drawnMatches = new MatOfByte();
if (aInputFrame.empty() || aInputFrame.cols() < 1 || aInputFrame.rows() < 1) {
return aInputFrame;
}
Features2d.drawMatches(img1, keypoints1, aInputFrame, keypoints2, goodMatches, outputImg, GREEN, RED, drawnMatches, Features2d.NOT_DRAW_SINGLE_POINTS);
Imgproc.resize(outputImg, outputImg, aInputFrame.size());
double matchPercentage = goodMatchesSum/ (double) good_matches.size();
if(matchPercentage/count >= 5)
{
match_count ++;
if(match_count > 20)
{
"good match"
}
}
else if (matchPercentage/count < 5)
{
"Bad match, compare next image"
}
return outputImg;
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
return recognize(inputFrame.rgba());
}
}