我在计算SIFT探测器找到的关键点的ORB描述符时遇到很大问题。如果我尝试运行一个简单的示例程序,整个系统会冻结,我无法弄清楚原因。示例代码如下:
import static com.googlecode.javacv.cpp.opencv_highgui.cvLoadImageM;
import com.googlecode.javacv.cpp.opencv_core.CvMat;
import com.googlecode.javacv.cpp.opencv_features2d.DescriptorExtractor;
import com.googlecode.javacv.cpp.opencv_features2d.FeatureDetector;
import com.googlecode.javacv.cpp.opencv_features2d.KeyPoint;
import com.googlecode.javacv.cpp.opencv_features2d.ORB;
import com.googlecode.javacv.cpp.opencv_nonfree.SIFT;
public class DescriptorTest {
public static void main(String[] args) {
SIFT sift = new SIFT(0, 3, 0.04, 10, 1.6);
FeatureDetector detector = sift.getFeatureDetector();
ORB orb_descriptor = new ORB(500, 1.2f, 8, 31, 0, 2, 0, 31);
DescriptorExtractor descriptor = orb_descriptor.getDescriptorExtractor();
CvMat image = cvLoadImageM("res/dvd_009_ref.jpg");
KeyPoint keypoints = new KeyPoint();
CvMat descriptors = new CvMat(null);
detector.detect(image, keypoints, null);
System.out.println("Keypoints found: "+ keypoints.capacity());
descriptor.compute(image, keypoints, descriptors);
System.out.println("Descriptors calculated: "+descriptors.rows());
}
}
有谁知道问题是什么?会很棒:))
答案 0 :(得分:1)
好吧,所以如果我把关键点的八度设置为0似乎有效。我不知道这是不是一个好主意但我倾向于拒绝。因为对于某些描述符,已经找到该特征的尺度 - 空间八度的信息是至关重要的。
for(int i = 0; i < keypoints.capacity(); i++) {
KeyPoint kp = keypoints.position(i);
kp.octave(0);
}
keypoints.position(0);
答案 1 :(得分:1)
我不知道这对您是否有帮助您可能想要查看Vladislav Vinogradov(http://code.opencv.org/issues/2987)在此给出的解决方法(http://code.opencv.org/users/340)。虽然这是一个c ++代码,但我相信你会明白这个想法:
void unpackSIFTOctave(const KeyPoint& kpt, int& octave, int& layer, float& scale)
{
octave = kpt.octave & 255;
layer = (kpt.octave >> 8) & 255;
octave = octave < 128 ? octave : (-128 | octave);
scale = octave >= 0 ? 1.f/(1 << octave) : (float)(1 << -octave);
}
这是暂时的已知问题,他们似乎没有计划修复它。
(是的,您可能希望保留关键点的数据,因为描述提取过程可能会使用那些是缩放/旋转不变的,而八度信息通常与关键点的“本地”描述是如何相关的)
希望这会有所帮助,(并且不需要再次编辑:))
V