The homography tutorial in java
EDIT : main problem solved (see in comments) ! But i now have a problem with perspectiveTransform()...
OpenCV Error: Assertion failed (scn + 1 == m.cols && (depth == CV_32F || depth == CV_64F)) in unknown function, file ......\src\opencv\modules\core\src\matmul.cpp, line 1926
Original post
Hi,
i'm trying to redo this tutorial in Java... but it doesn't work. The findHomography function didn't work, and the error message isn't very clear for me :
OpenCV Error: Assertion failed (npoints >= 0 && points2.checkVector(2) == npoints && points1.type() == points2.type()) in unknown function, file ..\..\..\src\opencv\modules\calib3d\src\fundam.cpp, line 1074
I realy hope someone will be able to help me... i'm a novice with OpenCV
Here is my code, sorry it's a bit long :
CODE UPDATED
class FindObject {
public void run(String pathObject, String pathScene, String pathResult) {
System.out.println("\nRunning FindObject");
Mat img_object = Highgui.imread("D:/workspaceSeirich/HelloCV/".concat(pathObject), 0); //0 = CV_LOAD_IMAGE_GRAYSCALE
Mat img_scene = Highgui.imread("D:/workspaceSeirich/HelloCV/".concat(pathScene), 0);
FeatureDetector detector = FeatureDetector.create(4); //4 = SURF
MatOfKeyPoint keypoints_object = new MatOfKeyPoint();
MatOfKeyPoint keypoints_scene = new MatOfKeyPoint();
detector.detect(img_object, keypoints_object);
detector.detect(img_scene, keypoints_scene);
DescriptorExtractor extractor = DescriptorExtractor.create(2); //2 = SURF;
Mat descriptor_object = new Mat();
Mat descriptor_scene = new Mat() ;
extractor.compute(img_object, keypoints_object, descriptor_object);
extractor.compute(img_scene, keypoints_scene, descriptor_scene);
DescriptorMatcher matcher = DescriptorMatcher.create(1); // 1 = FLANNBASED
MatOfDMatch matches = new MatOfDMatch();
matcher.match(descriptor_object, descriptor_scene, matches);
List<DMatch> matchesList = matches.toList();
Double max_dist = 0.0;
Double min_dist = 100.0;
for(int i = 0; i < descriptor_object.rows(); i++){
Double dist = (double) matchesList.get(i).distance;
if(dist < min_dist) min_dist = dist;
if(dist > max_dist) max_dist = dist;
}
System.out.println("-- Max dist : " + max_dist);
System.out.println("-- Min dist : " + min_dist);
LinkedList<DMatch> good_matches = new LinkedList<DMatch>();
MatOfDMatch gm = new MatOfDMatch();
for(int i = 0; i < descriptor_object.rows(); i++){
if(matchesList.get(i).distance < 3*min_dist){
good_matches.addLast(matchesList.get(i));
}
}
gm.fromList(good_matches);
Mat img_matches = new Mat();
Features2d.drawMatches(
img_object,
keypoints_object,
img_scene,
keypoints_scene,
gm,
img_matches,
new Scalar(255,0,0),
new Scalar(0,0,255),
new MatOfByte(),
2);
LinkedList<Point> objList = new LinkedList<Point>();
LinkedList<Point> sceneList = new LinkedList<Point>();
List<KeyPoint> keypoints_objectList = keypoints_object.toList();
List<KeyPoint> keypoints_sceneList = keypoints_scene.toList();
for(int i = 0; i<good_matches.size(); i++){
objList.addLast(keypoints_objectList.get(good_matches.get(i).queryIdx).pt);
sceneList.addLast(keypoints_sceneList.get(good_matches.get(i).trainIdx).pt);
}
MatOfPoint2f obj = new MatOfPoint2f();
obj.fromList(objList);
MatOfPoint2f scene = new MatOfPoint2f();
scene.fromList(sceneList);
Mat H = Calib3d.findHomography(obj, scene);
LinkedList<Point> cornerList = new LinkedList<Point>();
cornerList.add(new Point(0,0));
cornerList.add(new Point(img_object.cols(),0));
cornerList.add(new Point(img_object.cols(),img_object.rows()));
cornerList.add(new Point(0,img_object.rows()));
MatOfPoint obj_corners = new MatOfPoint();
obj_corners.fromList(cornerList);
MatOfPoint scene_corners = new MatOfPoint();
//ERROR HERE :
//OpenCV Error: Assertion failed (scn + 1 == m.cols && (depth == CV_32F || depth == CV_64F)) in unknown function, file ..\..\..\src\opencv\modules\core\src\matmul.cpp, line 1926
Core.perspectiveTransform(obj_corners, scene_corners, H);
//Draw the lines... later, when the homography will work
/*
Core.line(img_matches, new Point(), new Point(), new ...
what happens, if you don't find any matches ? both obj and scene will be empty
Good questions... i've never try to detect an object which isn't present in the scene. I think it will find something weird because it always find some matching points.
you need at least 4 points (each) for findhomography, so you should already bail out after matcher.match(), if there's less matches
I've a lot more, i can see that if i only draw all the "good" matches (whose distance is less than 3*min_dist). Depending on the pictures, i've between 20 and 140 items in my 'good_matches' list (if i do a system.out.printn on it)
I think the problem probably come from those lines
But i can't find why...
oh, right. look again at the tutorial, it has:
as of java, i can only guess:
yes, you want a list of points there, not a list of KeyPoints
Oh yes ! I've totally forgot this details. We're on the good way (hum... i hope so...)
But there is no way to do .pt in java. And i don't find any getPt() function. Any idea ?
aw, sorry, more the c++ guy here, but http://docs.opencv.org/java/ states, KeyPoint has a pt
Okay, it's was a type problem... there is no way to extract from a Mat the good type. We've to use a list. It was, indeed, a problem of type before using findHomography(). The right way is :
LinkedList<Point> objList = new LinkedList<Point>(); LinkedList<Point> sceneList = new LinkedList<Point>();
for(int i = 0; i<good_matches.size(); i++){ objList.addLast(keypoints_objectList.get(good_matches.get(i).queryIdx).pt); sceneList.addLast(keypoints_sceneList.get(good_matches.get(i).trainIdx).pt); }
MatOfPoint2f obj = new MatOfPoint2f(); obj.fromList(objList);
Same with the scene, and then findHomography()
But i now have a problem some lines after, when i do perspectiveTransform(), i've an other ununderstandable error :
OpenCV Error: Assertion failed (scn + 1 == m.cols && (depth == CV_32F || depth == CV_64F)) in unknown function, file ......\src\opencv\modules\core\src\matmul.cpp, line 1926