/// <summary> /// シーケンスの要素を一つ読みだして、読み出しポインタを次へ1つ移動させる /// </summary> /// <param name="elem"></param> /// <param name="reader"></param> #else /// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="elem"></param> /// <param name="reader"></param> #endif public static void REV_READ_SEQ_ELEM <T>(out T elem, CvSeqReader reader) where T : struct { if (reader == null) { throw new ArgumentNullException("reader"); } //Type t = typeof(t); //if (t.IsValueType) { using (StructurePointer <T> elemPtr = new StructurePointer <T>()) { if (reader.Seq.ElemSize != elemPtr.Size) { throw new OpenCvSharpException(); } Util.CopyMemory(elemPtr.Ptr, reader.Ptr, elemPtr.Size); PREV_SEQ_ELEM(elemPtr.Size, reader); elem = elemPtr.ToStructure(); } } /* * else * { * IntPtr elemPtr; * REV_READ_SEQ_ELEM<IntPtr>(out elemPtr, reader); * elem = Util.ToObject<t>(elemPtr); * } * //*/ }
/// <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()); }
/// <summary> /// 次のシーケンスへ /// </summary> /// <param name="elemSize"></param> /// <param name="reader"></param> #else /// <summary> /// /// </summary> /// <param name="elemSize"></param> /// <param name="reader"></param> #endif public static void NEXT_SEQ_ELEM(int elemSize, CvSeqReader reader) { reader.Ptr = new IntPtr(reader.Ptr.ToInt64() + elemSize); if (reader.Ptr.ToInt64() >= reader.BlockMax.ToInt64()) { NativeMethods.cvChangeSeqBlock(reader.CvPtr, 1); } }
/// <summary> /// 前のシーケンスへ /// </summary> /// <param name="elemSize"></param> /// <param name="reader"></param> #else /// <summary> /// /// </summary> /// <param name="elemSize"></param> /// <param name="reader"></param> #endif public static void PREV_SEQ_ELEM(int elemSize, CvSeqReader reader) { reader.Ptr = new IntPtr(reader.Ptr.ToInt64() - elemSize); if (reader.Ptr.ToInt64() < reader.BlockMin.ToInt64()) { NativeMethods.cvChangeSeqBlock(reader.CvPtr, -1); } }
/// <summary> /// CvSeqReaderからCvQuadEdge2Dのインスタンスを読み込んで返す /// </summary> /// <param name="reader"></param> /// <returns></returns> #else /// <summary> /// Reads a CvQuadEdge2D instance from CvSeqReader /// </summary> /// <param name="reader"></param> /// <returns></returns> #endif public static CvQuadEdge2D FromSeqReader(CvSeqReader reader) { if (reader == null) { throw new ArgumentNullException("reader"); } return(new CvQuadEdge2D(reader.Ptr)); }
/// <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); } }
/// <summary> /// シーケンスからの連続読み出し処理を初期化する (cvStartReadSeq). /// </summary> /// <param name="reader">リーダ(reader)の状態.この関数で初期化される.</param> /// <param name="reverse">シーケンス走査方向の指定.reverse が false の場合,リーダは先頭のシーケンス要素に位置する.それ以外は最後の要素に位置する.</param> #else /// <summary> /// Initializes process of sequential reading from sequence (cvStartReadSeq). /// </summary> /// <param name="reader">Reader state; initialized by the function. </param> /// <param name="reverse">Determines the direction of the sequence traversal. If reverse is false, the reader is positioned at the first sequence element, otherwise it is positioned at the last element. </param> #endif public virtual void StartRead(CvSeqReader <T> reader, Boolean reverse) { Cv.StartReadSeq(this, reader, reverse); }
/// <summary> /// シーケンスからの連続読み出し処理を初期化する (cvStartReadSeq). /// </summary> /// <param name="reader">リーダ(reader)の状態.この関数で初期化される.</param> #else /// <summary> /// Initializes process of sequential reading from sequence (cvStartReadSeq). /// </summary> /// <param name="reader">Reader state; initialized by the function. </param> #endif public virtual void StartRead(CvSeqReader <T> reader) { Cv.StartReadSeq(this, reader); }
/// <summary> /// ファイルノードのシーケンスリーダの初期化 /// </summary> /// <param name="src">読み込むファイルノード(シーケンス).</param> /// <param name="reader">シーケンスリーダへのポインタ.</param> #else /// <summary> /// Initializes file node sequence reader /// </summary> /// <param name="src">The file node (a sequence) to read numbers from. </param> /// <param name="reader">Output reference to the sequence reader. </param> #endif public void StartReadRawData(CvFileNode src, out CvSeqReader reader) { Cv.StartReadRawData(this, src, out reader); }
/// <summary> /// 複数の数値のシーケンスを読み込む /// </summary> /// <typeparam name="T"></typeparam> /// <param name="reader">シーケンスリーダ</param> /// <param name="count">読み込む要素数</param> /// <param name="dst">出力配列</param> /// <param name="dt">各配列要素の仕様</param> #else /// <summary> /// Initializes file node sequence reader /// </summary> /// <typeparam name="T"></typeparam> /// <param name="reader">The sequence reader. Initialize it with cvStartReadRawData. </param> /// <param name="count">The number of elements to read. </param> /// <param name="dst">Destination array. </param> /// <param name="dt">Specification of each array element. It has the same format as in cvWriteRawData. </param> #endif public void ReadRawDataSlice <T>(CvSeqReader reader, int count, out T[] dst, string dt) where T : struct { Cv.ReadRawDataSlice(this, reader, count, out dst, dt); }
/// <summary> /// シーケンスからの連続読み出し処理を初期化する (cvStartReadSeq). /// </summary> /// <param name="reader">リーダ(reader)の状態.この関数で初期化される.</param> /// <param name="reverse">シーケンス走査方向の指定.reverse が false の場合,リーダは先頭のシーケンス要素に位置する.それ以外は最後の要素に位置する.</param> #else /// <summary> /// Initializes process of sequential reading from sequence (cvStartReadSeq). /// </summary> /// <param name="reader">Reader state; initialized by the function. </param> /// <param name="reverse">Determines the direction of the sequence traversal. If reverse is false, the reader is positioned at the first sequence element, otherwise it is positioned at the last element. </param> #endif public virtual void StartRead(CvSeqReader reader, bool reverse) { Cv.StartReadSeq(this, reader, reverse); }