/// <summary> /// 进行SIFT检测,并返回检测的结果 /// </summary> /// <param name="image">图像</param> /// <param name="resultType">SIFT检测的结果类型</param> /// <returns>返回SIFT检测结果——SIFT特征列表;如果检测失败,返回null。</returns> public List<SiftFeature> Process(Image<Gray, Single> image, SiftDetectorResultType resultType) { if (image.Width != SiftFilt.width || image.Height != SiftFilt.height) throw new ArgumentException("图像的尺寸和构造函数中指定的尺寸不一致。", "image"); return Process(image.MIplImage.ImageData, resultType); }
/// <summary> /// 进行SIFT检测,并返回检测的结果 /// </summary> /// <param name="im">单通道浮点型图像数据,图像数据不必归一化到区间[0,1]</param> /// <param name="resultType">SIFT检测的结果类型</param> /// <returns>返回SIFT检测结果——SIFT特征列表;如果检测失败,返回null。</returns> public unsafe List<SiftFeature> Process(IntPtr im, SiftDetectorResultType resultType) { //定义变量 List<SiftFeature> features = null; //检测结果:SIFT特征列表 VlSiftFilt siftFilt; // VlSiftKeypoint* pKeyPoints; //指向关键点的指针 VlSiftKeypoint keyPoint; //关键点 SiftKeyPointOrientation[] orientations; //关键点对应的方向及描述 double[] angles = new double[4]; //关键点对应的方向(角度) int angleCount; //某个关键点的方向数目 double angle; //方向 float[] descriptors; //关键点某个方向的描述 IntPtr ptrDescriptors = Marshal.AllocHGlobal(128 * sizeof(float)); //指向描述的缓冲区指针 //依次遍历每一阶 if (VlFeatInvoke.vl_sift_process_first_octave(ptrSiftFilt, im) != VlFeatInvoke.VL_ERR_EOF) { features = new List<SiftFeature>(100); while (true) { //计算每组中的关键点 VlFeatInvoke.vl_sift_detect(ptrSiftFilt); //遍历每个点 siftFilt = (VlSiftFilt)Marshal.PtrToStructure(ptrSiftFilt, typeof(VlSiftFilt)); pKeyPoints = (VlSiftKeypoint*)siftFilt.keys.ToPointer(); for (int i = 0; i < siftFilt.nkeys; i++) { keyPoint = *pKeyPoints; pKeyPoints++; orientations = null; if (resultType == SiftDetectorResultType.Normal || resultType == SiftDetectorResultType.Extended) { //计算并遍历每个点的方向 angleCount = VlFeatInvoke.vl_sift_calc_keypoint_orientations(ptrSiftFilt, angles, ref keyPoint); orientations = new SiftKeyPointOrientation[angleCount]; for (int j = 0; j < angleCount; j++) { angle = angles[j]; descriptors = null; if (resultType == SiftDetectorResultType.Extended) { //计算每个方向的描述 VlFeatInvoke.vl_sift_calc_keypoint_descriptor(ptrSiftFilt, ptrDescriptors, ref keyPoint, angle); descriptors = new float[128]; Marshal.Copy(ptrDescriptors, descriptors, 0, 128); } orientations[j] = new SiftKeyPointOrientation(angle, descriptors); //保存关键点方向和描述 } } features.Add(new SiftFeature(keyPoint, orientations)); //将得到的特征添加到列表中 } //下一阶 if (VlFeatInvoke.vl_sift_process_next_octave(ptrSiftFilt) == VlFeatInvoke.VL_ERR_EOF) break; } } //释放资源 Marshal.FreeHGlobal(ptrDescriptors); //返回 return features; }