I am working on object recognition in android using openCV. Below are my usecase .
1) I have static images in my drawable(I have captured these images using my mobile cam and stored in drawable) 2)Then I'M capturing the same image using my mobile and start comparing with my drawable images.
Unfortunately I am not getting the good results , Below are my code snippet.
Scalar RED = new Scalar(255,0,0);
Scalar GREEN = new Scalar(0,255,0);
Mat objectImage = Highgui.imread(cameraimage, Highgui.CV_LOAD_IMAGE_COLOR);
Mat sceneImage = Highgui.imread(databaseimage, Highgui.CV_LOAD_IMAGE_COLOR);
Size sz = new Size(200,200);
Imgproc.resize( objectImage, objectImage, sz );
Imgproc.resize( sceneImage, sceneImage, sz );
MatOfKeyPoint objectKeyPoints = new MatOfKeyPoint();
FeatureDetector featureDetector = FeatureDetector.create(FeatureDetector.SIFT);
featureDetector.detect(objectImage, objectKeyPoints);
KeyPoint[] keypoints = objectKeyPoints.toArray();
System.out.println("Object keypoints length:"+keypoints.length);
MatOfKeyPoint objectDescriptors = new MatOfKeyPoint();
DescriptorExtractor descriptorExtractor = DescriptorExtractor.create(DescriptorExtractor.SIFT);
descriptorExtractor.compute(objectImage, objectKeyPoints, objectDescriptors);
// Create the matrix for output image.
Mat outputImage = new Mat(objectImage.rows(), objectImage.cols(), Highgui.CV_LOAD_IMAGE_COLOR);
Scalar newKeypointColor = new Scalar(255, 0, 0);
Features2d.drawKeypoints(objectImage, objectKeyPoints, outputImage, newKeypointColor, 0);
MatOfKeyPoint sceneKeyPoints = new MatOfKeyPoint();
MatOfKeyPoint sceneDescriptors = new MatOfKeyPoint();
System.out.println("Detecting key points in background image...");
featureDetector.detect(sceneImage, sceneKeyPoints);
System.out.println("sceneKeyPoints length:"+sceneKeyPoints.toArray().length);
System.out.println("Computing descriptors in background image...");
descriptorExtractor.compute(sceneImage, sceneKeyPoints, sceneDescriptors);
Mat matchoutput = new Mat(sceneImage.rows() * 2, sceneImage.cols() * 2, Highgui.CV_LOAD_IMAGE_COLOR);
Scalar matchestColor = new Scalar(0, 255, 0);
List<MatOfDMatch> matches = new LinkedList<MatOfDMatch>();
DescriptorMatcher descriptorMatcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);
System.out.println("Matching object and scene images...");
descriptorMatcher.knnMatch(objectDescriptors, sceneDescriptors, matches, 2);
System.out.println("Calculating good match list..matchessize."+matches.size());
LinkedList<DMatch> goodMatchesList = new LinkedList<DMatch>();
//float nndrRatio = 0.8f;
float nndrRatio = 0.7f;
for (int i = 0; i < matches.size(); i++) {
MatOfDMatch matofDMatch = matches.get(i);
DMatch[] dmatcharray = matofDMatch.toArray();
DMatch m1 = dmatcharray[0];
DMatch m2 = dmatcharray[1];
if (m1.distance <= m2.distance * nndrRatio) {
goodMatchesList.addLast(m1);
}
}
if (goodMatchesList.size() >= 7) {
System.out.println("Object Found!!!");
List<KeyPoint> objKeypointlist = objectKeyPoints.toList();
List<KeyPoint> scnKeypointlist = sceneKeyPoints.toList();
LinkedList<Point> objectPoints = new LinkedList<>();
LinkedList<Point> scenePoints = new LinkedList<>();
for (int i = 0; i < goodMatchesList.size(); i++) {
objectPoints.addLast(objKeypointlist.get(goodMatchesList.get(i).queryIdx).pt);
scenePoints.addLast(scnKeypointlist.get(goodMatchesList.get(i).trainIdx).pt);
}
MatOfPoint2f objMatOfPoint2f = new MatOfPoint2f();
objMatOfPoint2f.fromList(objectPoints);
MatOfPoint2f scnMatOfPoint2f = new MatOfPoint2f();
scnMatOfPoint2f.fromList(scenePoints);
Mat mask=new Mat();
Mat homography = Calib3d.findHomography(objMatOfPoint2f, scnMatOfPoint2f, Calib3d.RANSAC, 3,mask);
Mat obj_corners = new Mat(4, 1, CvType.CV_32FC2);
Mat scene_corners = new Mat(4, 1, CvType.CV_32FC2);
obj_corners.put(0, 0, new double[]{0, 0});
obj_corners.put(1, 0, new double[]{objectImage.cols(), 0});
obj_corners.put(2, 0, new double[]{objectImage.cols(), objectImage.rows()});
obj_corners.put(3, 0, new double[]{0, objectImage.rows()});
System.out.println("Transforming object corners to scene corners...");
Core.perspectiveTransform(obj_corners, scene_corners, homography);
Mat img = Highgui.imread(databaseimage, Highgui.CV_LOAD_IMAGE_COLOR);
Core.line(img, new Point(scene_corners.get(0, 0)), new Point(scene_corners.get(1, 0)), new Scalar(0, 255, 0), 4);
Core.line(img, new Point(scene_corners.get(1, 0)), new Point(scene_corners.get(2, 0)), new Scalar(0, 255, 0), 4);
Core.line(img, new Point(scene_corners.get(2, 0)), new Point(scene_corners.get(3, 0)), new Scalar(0, 255, 0), 4);
Core.line(img, new Point(scene_corners.get(3, 0)), new Point(scene_corners.get(0, 0)), new Scalar(0, 255, 0), 4);
System.out.println("Drawing matches image...");
MatOfDMatch goodMatches = new MatOfDMatch();
goodMatches.fromList(goodMatchesList);
Features2d.drawMatches(objectImage, objectKeyPoints, sceneImage, sceneKeyPoints, goodMatches, matchoutput, matchestColor, newKeypointColor, new MatOfByte(), 2);
Highgui.imwrite("output//outputImage.jpg", outputImage);
Highgui.imwrite("output//matchoutput.jpg", matchoutput);
Highgui.imwrite("output//img.jpg", img);
int count=0;
int size = (int) mask.size().height;
for(int i = 0; i < size; i++){
if ( mask.get(i, 0)[0] == 1){
count++;
}
}
System.out.println("Maskcount is...." + count);
Bitmap matchoutputbmp = Bitmap.createBitmap(matchoutput.cols(), matchoutput.rows(),
Bitmap.Config.ARGB_8888);
//Highgui.cvtColor(img3, img3, Imgproc.COLOR_BGR2RGB);
Utils.matToBitmap(matchoutput, matchoutputbmp);
System.out.println("Drawing matches image..." + outputImage);
}
}
When i am checking the good Matches size, it is giving less-than 7 and when i search for matches size(descriptorMatcher.knnMatch(objectDescriptors, sceneDescriptors, matches, 2) every time that size is equal to my Object image keypoints length.
I searched on google a lot, but no luck.I have to submit my final project on this week, please please please help me and suggest me if any changes are required on my code .
Note: I tired with ORB also but no luck