PSURF - image matching after scaling/transformation
in
Contributed Library Questions
•
10 months ago
Hello!
First of all the PSURF libary is great for image matching. It goes deep enough into SURF to be very effective, yet provides a simple high level implementation for beginners like me to use.
Just two questions : I am getting a image-matching frame rate of about 0.5 fps. Is this normal? Should I be getting it faster since this is SpeededUpRobustFeatures (SURF)?
More importantly, does the code I have implemented shown below include the matching processes after transformation and scaling? I am definitely generating the "descriptors" but do they already compute these transformations/scaling or should I be handling it in the implementation itself?
Many Thanks! Here is my code, for all who are interested.
import processing.video.*;
import surf.*;
//-----------------------
Capture cam;
//ArrayList interest_points;
float threshold = 640;
float balanceValue = 0.9;
int octaves = 4;
int framenumber = 0;
//-----------------------
ArrayList<Interest_Point> imageToSearchInto;
ArrayList<Interest_Point> matchingInterestPoints = new ArrayList<Interest_Point>();
ArrayList<Interest_Point> InterestPointOfTheBanner;
//-----------------------
void setup() {
PImage img = loadImage("nutellajar.jpeg");
size(img.width,img.height);
image(img, 0, 0);
loadPixels();
SURF_Factory mySURF = SURF.createInstance(img, balanceValue, threshold, octaves, this);
Detector detector = mySURF.createDetector();
//interest_points = detector.generateInterestPoints();
InterestPointOfTheBanner = detector.generateInterestPoints();
Descriptor descriptor = mySURF.createDescriptor(InterestPointOfTheBanner);
descriptor.generateAllDescriptors();
//drawInterestPoints();
//drawDescriptors();
//---------------------------------------------------------------
size(640, 480);
String[] cameras = Capture.list();
if (cameras.length == 0) {
println("There are no cameras available for capture.");
exit();
} else {
println("Available cameras:");
for (int i = 0; i < cameras.length; i++) {
println(cameras[i]);
}
// The camera can be initialized directly using an
// element from the array returned by list():
cam = new Capture(this, cameras[0]);
cam.start();
}
}
void draw() {
if (cam.available() == true) {
cam.read();
}
image(cam, 0, 0);
saveFrame(framenumber+".jpeg");
PImage img1 = loadImage(framenumber+".jpeg");
//PImage img1 = loadImage("nutellajar.jpeg");
//framenumber += 1;
size(img1.width,img1.height);
//image(img1, 0, 0);
// The following does the same, and is faster when just drawing the image
// without any additional resizing, transformations, or tint.
//set(0, 0, cam);
//--------------------------------------------------------------------------------------
loadPixels();
SURF_Factory mySURF1 = SURF.createInstance(img1, balanceValue, threshold, octaves, this);
Detector detector1 = mySURF1.createDetector();
imageToSearchInto = detector1.generateInterestPoints();
Descriptor descriptor1 = mySURF1.createDescriptor(imageToSearchInto);
descriptor1.generateAllDescriptors();
findMeHere();
if (InterestPointOfTheBanner.size()/matchingInterestPoints.size() < 10){
println(InterestPointOfTheBanner.size());
println(matchingInterestPoints.size());
println("NUTELLA FOUND!!");
matchingInterestPoints = new ArrayList<Interest_Point>();
}
}
public void findMeHere() {
Interest_Point target;
for (int i=0; i<InterestPointOfTheBanner.size(); i++) {
target = InterestPointOfTheBanner.get(i);
//Look for the best match in imageToSeachInto
Interest_Point best = getBest(target, imageToSearchInto);
if (euclideanDistance(target, best) < 0.8) {
// Found! Adding to matching IP
matchingInterestPoints.add(best);
// I remove the IP to the ones to be used for new matching
imageToSearchInto.remove(best);
}
}
}
public double euclideanDistance(Interest_Point target, Interest_Point another_point) {
float[] targetDescriptor = target.getDescriptorOfTheInterestPoint();
float[] theOtherOneDescriptor = another_point.getDescriptorOfTheInterestPoint();
double distance = 0;
//jeremynotes cos this is 64 dimensions so i<64
for (int i=0; i<64; i++) {
distance += Math.pow(targetDescriptor[i] - theOtherOneDescriptor[i], 2);
}
return Math.sqrt(distance);
}
public Interest_Point getBest(Interest_Point referencetarget, ArrayList<Interest_Point> imageToSearchInto){
float reftargetx = referencetarget.getX();
float reftargety = referencetarget.getY();
double currentdist = 0;
double shortestdist = 0;
Interest_Point imagetarget;
Interest_Point bestmatch = referencetarget;
for (int i=0; i < imageToSearchInto.size(); i++) {
imagetarget = imageToSearchInto.get(i);
currentdist = sqrt(abs(imagetarget.getX()-reftargetx)*abs(imagetarget.getX()-reftargetx) + abs(imagetarget.getY()-reftargety)*abs(imagetarget.getY()-reftargety));
if(i==0){
shortestdist = currentdist;
bestmatch = imagetarget;
}
if(currentdist<shortestdist){
bestmatch = imagetarget;
}
}
//println(shortestdist);
return bestmatch;
}
1