Example #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="objectKeypoints"></param>
        /// <param name="objectDescriptors"></param>
        /// <param name="imageKeypoints"></param>
        /// <param name="imageDescriptors"></param>
        /// <returns></returns>
        private static int[] FindPairs(CvSeq <CvSURFPoint> objectKeypoints, CvSeq <float> objectDescriptors, CvSeq <CvSURFPoint> imageKeypoints, CvSeq <float> imageDescriptors)
        {
            CvSeqReader <float>       reader  = new CvSeqReader <float>();
            CvSeqReader <CvSURFPoint> kreader = new CvSeqReader <CvSURFPoint>();

            Cv.StartReadSeq(objectDescriptors, reader);
            Cv.StartReadSeq(objectKeypoints, kreader);

            List <int> ptpairs = new List <int>();

            for (int i = 0; i < objectDescriptors.Total; i++)
            {
                CvSURFPoint kp         = CvSURFPoint.FromPtr(kreader.Ptr);
                IntPtr      descriptor = reader.Ptr;
                Cv.NEXT_SEQ_ELEM(kreader.Seq.ElemSize, kreader);
                Cv.NEXT_SEQ_ELEM(reader.Seq.ElemSize, reader);
                int nearestNeighbor = NaiveNearestNeighbor(descriptor, kp.Laplacian, imageKeypoints, imageDescriptors);
                if (nearestNeighbor >= 0)
                {
                    ptpairs.Add(i);
                    ptpairs.Add(nearestNeighbor);
                }
            }
            return(ptpairs.ToArray());
        }
Example #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="vec">Cではconst float*</param>
        /// <param name="laplacian"></param>
        /// <param name="model_keypoints"></param>
        /// <param name="model_descriptors"></param>
        /// <returns></returns>
        private static int NaiveNearestNeighbor(IntPtr vec, int laplacian, CvSeq <CvSURFPoint> model_keypoints, CvSeq <float> model_descriptors)
        {
            int    length = (int)(model_descriptors.ElemSize / sizeof(float));
            int    neighbor = -1;
            double dist1 = 1e6, dist2 = 1e6;
            CvSeqReader <float>       reader = new CvSeqReader <float>();
            CvSeqReader <CvSURFPoint> kreader = new CvSeqReader <CvSURFPoint>();

            Cv.StartReadSeq(model_keypoints, kreader, false);
            Cv.StartReadSeq(model_descriptors, reader, false);

            IntPtr      mvec;
            CvSURFPoint kp;
            double      d;

            for (int i = 0; i < model_descriptors.Total; i++)
            {
                // const CvSURFPoint* kp = (const CvSURFPoint*)kreader.ptr; が結構曲者。
                // OpenCvSharpの構造体はFromPtrでポインタからインスタンス生成できるようにしてるので、こう書ける。
                kp = CvSURFPoint.FromPtr(kreader.Ptr);
                // まともにキャストする場合はこんな感じか
                // CvSURFPoint kp = (CvSURFPoint)Marshal.PtrToStructure(kreader.Ptr, typeof(CvSURFPoint));

                mvec = reader.Ptr;
                Cv.NEXT_SEQ_ELEM(kreader.Seq.ElemSize, kreader);
                Cv.NEXT_SEQ_ELEM(reader.Seq.ElemSize, reader);
                if (laplacian != kp.Laplacian)
                {
                    continue;
                }
                d = CompareSurfDescriptors(vec, mvec, dist2, length);
                if (d < dist1)
                {
                    dist2    = dist1;
                    dist1    = d;
                    neighbor = i;
                }
                else if (d < dist2)
                {
                    dist2 = d;
                }
            }
            if (dist1 < 0.6 * dist2)
            {
                return(neighbor);
            }
            else
            {
                return(-1);
            }
        }