private void tmpDrawBoxes(ref IplImage gimg) { IplImage img8uc3 = new IplImage(gimg.Size, BitDepth.U8, 3); Cv.CvtColor(gimg, img8uc3, ColorConversion.GrayToBgr); int count = TargetList.Count; for (int i = 0; i < count; i++) { sMarkerInfo s = new sMarkerInfo(); s = (sMarkerInfo)TargetList[i]; Cv.DrawLine(img8uc3, new CvPoint((int)s.corner[0].X, (int)s.corner[0].Y), new CvPoint((int)s.corner[1].X, (int)s.corner[1].Y), Cv.RGB(255, 0, 0), 10); Cv.DrawLine(img8uc3, new CvPoint((int)s.corner[1].X, (int)s.corner[1].Y), new CvPoint((int)s.corner[2].X, (int)s.corner[2].Y), Cv.RGB(255, 0, 0), 10); Cv.DrawLine(img8uc3, new CvPoint((int)s.corner[2].X, (int)s.corner[2].Y), new CvPoint((int)s.corner[3].X, (int)s.corner[3].Y), Cv.RGB(255, 0, 0), 10); Cv.DrawLine(img8uc3, new CvPoint((int)s.corner[0].X, (int)s.corner[0].Y), new CvPoint((int)s.corner[3].X, (int)s.corner[3].Y), Cv.RGB(255, 0, 0), 10); } IplImage timg = new IplImage(new CvSize(800, 600), BitDepth.U8, 3); Cv.Resize(img8uc3, timg); Cv.ShowImage("contours", timg); img8uc3.ReleaseData(); timg.ReleaseData(); /* if (contours != null) { Cv.DrawContours(img8uc3, contours, Cv.RGB(250, 0, 0), Cv.RGB(0, 0, 250), 1, 2, LineType.Link8); } IplImage timg = new IplImage(new CvSize(800, 600), BitDepth.U8, 3); Cv.Resize(img8uc3, timg); Cv.ShowImage("contours", timg); img8uc3.ReleaseData(); timg.ReleaseData(); * */ }
private void FindMarkerInContour(ref CvSeq<CvPoint> contours, ref CvMemStorage storage) { CvSeq<CvPoint> stpt = contours; for (CvSeq<CvPoint> s = contours; s != null;s = s.HNext) { if (s.Total >= 4) { CvRect rect = Cv.BoundingRect(s); double d = Math.Sqrt((double)(rect.Height * rect.Width)); double d_th = 12; double approx_param = 0.1; //최대길이가 12픽셀 이하인 것들은 제외 if (d <= d_th) continue; CvMemStorage storage3 = new CvMemStorage(0); CvSeq<CvPoint> ss = Cv.ApproxPoly(s, s.HeaderSize, storage3, ApproxPolyMethod.DP, d * approx_param, false); //단순화 결과 4각형인 것들만 통과 if (ss.Total == 4) { CvPoint2D32f center = new CvPoint2D32f(0, 0); if (IsMarkerBoundingRect(ref ss, ref center)) { sMarkerInfo mi = new sMarkerInfo(); mi.width = 0.141f; mi.height = 0.141f; mi.ID = -1; mi.center = center; mi.corner[0] = (CvPoint2D32f)Cv.GetSeqElem<CvPoint>(ss, 0); mi.corner[1] = (CvPoint2D32f)Cv.GetSeqElem<CvPoint>(ss, 1); mi.corner[2] = (CvPoint2D32f)Cv.GetSeqElem<CvPoint>(ss, 2); mi.corner[3] = (CvPoint2D32f)Cv.GetSeqElem<CvPoint>(ss, 3); TargetList.Add(mi); } } ss.ClearSeq(); Cv.ReleaseMemStorage(storage3); } if (s.VNext != null) { CvSeq<CvPoint> tt = s.VNext; FindMarkerInContour(ref tt, ref storage); } s.ClearSeq(); } }
bool pointInPolygon(ref sMarkerInfo s1, ref sMarkerInfo s2) { bool[] b = new bool[4]; for(int x=0; x< 4; x++) { b[x] = false; } for (int x = 0; x < s1.corner.Length; x++) { Point p = new Point((int)s1.corner[x].X, (int)s1.corner[x].Y); Point p1, p2; Point[] poly = new Point[4]; for (int k = 0; k < 4; k++) { poly[k] = new Point((int)s2.corner[k].X, (int)s2.corner[k].Y); } bool inside = false; var oldPoint = new Point( poly[poly.Length - 1].X, poly[poly.Length - 1].Y); for (int i = 0; i < poly.Length; i++) { var newPoint = new Point(poly[i].X, poly[i].Y); if (newPoint.X > oldPoint.X) { p1 = oldPoint; p2 = newPoint; } else { p1 = newPoint; p2 = oldPoint; } if ((newPoint.X < p.X) == (p.X <= oldPoint.X) && (p.Y - (long)p1.Y) * (p2.X - p1.X) < (p2.Y - (long)p1.Y) * (p.X - p1.X)) { inside = !inside; } oldPoint = newPoint; } b[x] = inside; } int num = 0; for (int x = 0; x < 4; x++) { if (b[x]) num++; } if (num >= 3) return true; else return false; }
private void ExtractMakerImage(ref IplImage src, ref IplImage dst, ref sMarkerInfo mi) { float ignoring_margin = 0.0f; CvPoint2D32f[] dest_corner = new CvPoint2D32f[4]; dest_corner[0] = new CvPoint2D32f(-ignoring_margin, -ignoring_margin); dest_corner[1] = new CvPoint2D32f(-ignoring_margin, dst.Height + ignoring_margin); dest_corner[2] = new CvPoint2D32f(dst.Width + ignoring_margin, dst.Height + ignoring_margin); dest_corner[3] = new CvPoint2D32f(dst.Width + ignoring_margin, -ignoring_margin); CvMat transform_matrix = Cv.CreateMat(3, 3, MatrixType.F32C1); Cv.GetPerspectiveTransform(mi.corner, dest_corner, out transform_matrix); Cv.WarpPerspective(src, dst, transform_matrix); Cv.ReleaseMat(transform_matrix); }