Example #1
0
        public static void DrawLine(Line line, Rectangle area, ref Image <Gray, byte> lineImage)
        {
            Point?FirstPoint = null;
            Point?LastPoint  = null;

            for (int x = area.X; x < area.X + area.Width; x++)
            {
                var y = line.CalcY(x);
                if (y < area.Y + area.Height && area.Y < y)
                {
                    if (FirstPoint == null)
                    {
                        FirstPoint = new Point(x, (int)y);
                    }
                    LastPoint = new Point(x, (int)y);
                }
            }

            var img = lineImage.CopyBlank();

            if (FirstPoint == null || LastPoint == null)
            {
                FirstPoint = new Point((int)line.X, area.Y);
                LastPoint  = new Point((int)line.X, area.Y + area.Height);
                if (line.Reverse)
                {
                    CvInvoke.ArrowedLine(img, (Point)LastPoint, (Point)FirstPoint, new MCvScalar(255), 1);
                }
                else
                {
                    CvInvoke.ArrowedLine(img, (Point)FirstPoint, (Point)LastPoint, new MCvScalar(255), 1);
                }
            }
            else
            {
                if (line.Reverse)
                {
                    CvInvoke.ArrowedLine(img, (Point)LastPoint, (Point)FirstPoint, new MCvScalar(255), 1);
                }
                else
                {
                    CvInvoke.ArrowedLine(img, (Point)FirstPoint, (Point)LastPoint, new MCvScalar(255), 1);
                }
            }
            lineImage.SetValue(new Gray(255), img);
        }
Example #2
0
        public void Draw(Mat image)
        {
            foreach (MyBlob blob in blobs)
            {
                CvInvoke.Circle(image, blob.LastPoint(), 2, new Emgu.CV.Structure.MCvScalar(0, 0, 255), -1);
                CvInvoke.PutText(
                    image,
                    blob.name,
                    blob.LastPoint(),
                    Emgu.CV.CvEnum.FontFace.HersheyComplex,
                    1, new Emgu.CV.Structure.MCvScalar(255, 255, 255));

                CvInvoke.ArrowedLine(image, blob.LastPoint(),
                                     new Point(
                                         blob.LastPoint().X + blob.LastVector().X,
                                         blob.LastPoint().Y + blob.LastVector().Y),
                                     new MCvScalar(255, 0, 255), 5, Emgu.CV.CvEnum.LineType.EightConnected, 0, 0.5);
            }
        }
Example #3
0
        private void RetrieveFrame(object sender, EventArgs arg)
        {
            Mat   diff   = new Mat();
            Point center = Point.Empty;

            // retrieve image from camera
            Mat frame = new Mat();

            Camera.Retrieve(frame);
            ImageSize = frame.Size;

            // generate diff image (before drawing stuff)
            if (!ImgRef.IsEmpty && !IsTuning)
            {
                CvInvoke.AbsDiff(frame, ImgRef, diff);
            }

            if (!IsTracking)
            {
                // find marker
                Rectangle boundingBox;
                if (Roi.IsEmpty)
                {
                    center = FindMarker(frame, out boundingBox);
                }
                else
                {
                    using (Mat crop = new Mat(frame.Clone(), Roi))
                    {
                        center = FindMarker(crop, out boundingBox);
                        if (!center.IsEmpty)
                        {
                            center.X      += Roi.X;
                            center.Y      += Roi.Y;
                            boundingBox.X += Roi.X;
                            boundingBox.Y += Roi.Y;
                        }
                    }
                }

                // store marker point
                if (ScheduleTakeReference && !center.IsEmpty)
                {
                    ImgRef        = frame.Clone();
                    PointRef      = center;
                    MarkerTracker = new TrackerCSRT();
                    MarkerTracker.Init(ImgRef, boundingBox);
                    ScheduleTakeReference = false;
                    Invoke(new Action(() => UpdateInstructionText()));
                }

                // draw marker
                if (!center.IsEmpty)
                {
                    CvInvoke.Circle(frame, center, 4, new MCvScalar(0, 140, 255), -1);
                    CvInvoke.Rectangle(frame, boundingBox, new MCvScalar(0, 140, 255), 1);
                }

                // draw ROI
                if (!Roi.IsEmpty)
                {
                    using (Mat dark = new Mat(frame.Rows, frame.Cols, frame.Depth, 3))
                    {
                        dark.SetTo(new MCvScalar(1, 1, 1));
                        CvInvoke.Rectangle(dark, Roi, new MCvScalar(2, 2, 2), -1);
                        CvInvoke.Multiply(frame, dark, frame, 0.5);
                    }
                }

                ImgBoxRef.Image = frame;
            }
            else
            {
                // tracker
                if (MarkerTracker.Update(frame, out Rectangle trackingRect))
                {
                    center = new Point(trackingRect.X + trackingRect.Width / 2, trackingRect.Y + trackingRect.Height / 2);
                    CvInvoke.Circle(frame, center, 4, new MCvScalar(0, 140, 255), -1);
                    CvInvoke.Rectangle(frame, trackingRect, new MCvScalar(0, 140, 255), 1);
                }

                ImgBoxLive.Image = frame;
            }

            // update diff image box
            if (!diff.IsEmpty)
            {
                MCvScalar color = new MCvScalar(0, 140, 255);
                if (!center.IsEmpty)
                {
                    CvInvoke.Circle(diff, center, 4, color, -1);
                }
                if (!PointRef.IsEmpty)
                {
                    CvInvoke.Circle(diff, PointRef, 4, color, -1);
                }
                if (!center.IsEmpty && !PointRef.IsEmpty)
                {
                    string dist = CalcDistance(center, PointRef).ToString("0.0");
                    CvInvoke.ArrowedLine(diff, PointRef, center, color);
                    CvInvoke.PutText(diff, dist, new Point(5, diff.Height - 5), FontFace.HersheyComplexSmall, 1, color);
                }
                ImgBoxDiff.Image = diff;
            }

            // update status text
            Invoke(new Action(() => UpdateStatusText(PointRef, center)));
        }
Example #4
0
        // Calculate Sections, Assign Lines for Each Section and Draw on Image
        public Image <Hsv, byte> CalculateSections(Image <Hsv, byte> frameImg, int frameNumber = 0)
        {
            // resultant Image
            Image <Hsv, byte> img = new Image <Hsv, byte>(frameImg.Width, frameImg.Height);

            int w              = frameImg.Width;  // total width of image
            int h              = frameImg.Height; // total height of image
            int section_width  = w / 3;           // width for one section
            int section_height = h / 3;           // height for one section

            // width and height of all rectangles will be same
            top_left.Width    = top_middle.Width = top_right.Width = section_width;
            middle_left.Width = middle_middle.Width = middle_right.Width = section_width;
            bottom_left.Width = bottom_middle.Width = bottom_right.Width = section_width;

            top_left.Height    = top_middle.Height = top_right.Height = section_height;
            middle_left.Height = middle_middle.Height = middle_right.Height = section_height;
            bottom_left.Height = bottom_middle.Height = bottom_right.Height = section_height;

            // only starting point of each section will be different

            top_left.Y    = top_middle.Y = top_right.Y = 0; // same Y position for first row sections
            middle_left.Y = middle_middle.Y = middle_right.Y = section_height;
            bottom_left.Y = bottom_middle.Y = bottom_right.Y = 2 * section_height;

            top_left.X   = middle_left.X = bottom_left.X = 0;
            top_middle.X = middle_middle.X = bottom_middle.X = section_width;
            top_right.X  = middle_right.X = bottom_right.X = 2 * section_width;

            // drawing the rectangles on the Image
            CvInvoke.Rectangle(img, top_left, new Bgr(Color.Green).MCvScalar, 2);
            CvInvoke.Rectangle(img, top_middle, new Bgr(Color.Blue).MCvScalar, 2);
            CvInvoke.Rectangle(img, top_right, new Bgr(Color.Green).MCvScalar, 2);
            CvInvoke.Rectangle(img, middle_left, new Bgr(Color.Green).MCvScalar, 2);
            CvInvoke.Rectangle(img, middle_middle, new Bgr(Color.Blue).MCvScalar, 2);
            CvInvoke.Rectangle(img, middle_right, new Bgr(Color.Green).MCvScalar, 2);
            CvInvoke.Rectangle(img, bottom_left, new Bgr(Color.Green).MCvScalar, 2);
            CvInvoke.Rectangle(img, bottom_middle, new Bgr(Color.Blue).MCvScalar, 2);
            CvInvoke.Rectangle(img, bottom_right, new Bgr(Color.Green).MCvScalar, 2);

            // assigning the lines to their respective section list
            foreach (FeatureVectorOpticalFlow fv in all_lines)
            {
                // first row sections
                if (fv.line.P1.X < section_width &&
                    fv.line.P2.X < section_width &&
                    fv.line.P1.Y < section_height &&
                    fv.line.P2.Y < section_height)
                {
                    top_left_lines.Add(fv);
                }
                else if (fv.line.P1.X < 2 * section_width &&
                         fv.line.P2.X < 2 * section_width &&
                         fv.line.P1.Y < section_height && fv.line.P2.Y < section_height)
                {
                    top_middle_lines.Add(fv);
                }
                else if (fv.line.P1.X < w && fv.line.P2.X < w &&
                         fv.line.P1.Y < section_height &&
                         fv.line.P2.Y < section_height)
                {
                    top_right_lines.Add(fv);
                }

                // middle row sections
                else if (fv.line.P1.X < section_width &&
                         fv.line.P2.X < section_width &&
                         fv.line.P1.Y < 2 * section_height &&
                         fv.line.P2.Y < 2 * section_height)
                {
                    middle_left_lines.Add(fv);
                }
                else if (fv.line.P1.X < 2 * section_width &&
                         fv.line.P2.X < 2 * section_width &&
                         fv.line.P1.Y < 2 * section_height &&
                         fv.line.P2.Y < 2 * section_height)
                {
                    middle_middle_lines.Add(fv);
                }
                else if (fv.line.P1.X < w && fv.line.P2.X < w &&
                         fv.line.P1.Y < 2 * section_height &&
                         fv.line.P2.Y < 2 * section_height)
                {
                    middle_right_lines.Add(fv);
                }

                // third row sections
                else if (fv.line.P1.X < section_width &&
                         fv.line.P2.X < section_width &&
                         fv.line.P1.Y < h && fv.line.P2.Y < h)
                {
                    bottom_left_lines.Add(fv);
                }
                else if (fv.line.P1.X < 2 * section_width &&
                         fv.line.P2.X < 2 * section_width &&
                         fv.line.P1.Y < h && fv.line.P2.Y < h)
                {
                    bottom_middle_lines.Add(fv);
                }
                else if (fv.line.P1.X < w &&
                         fv.line.P2.X < w &&
                         fv.line.P1.Y < h &&
                         fv.line.P2.Y < h)
                {
                    bottom_right_lines.Add(fv);
                }
            }

            // get line with maximum Length from each section list of lines
            // And Draw the line on the image

            if (top_left_lines.Count > 0)
            {
                top_left_line = getBigLine(top_left_lines);
                CvInvoke.ArrowedLine(img, top_left_line.line.P1, top_left_line.line.P2, new Bgr(Color.White).MCvScalar, 1);
            }

            if (top_middle_lines.Count > 0)
            {
                top_middle_line = getBigLine(top_middle_lines);
                CvInvoke.ArrowedLine(img, top_middle_line.line.P1, top_middle_line.line.P2, new Bgr(Color.White).MCvScalar, 1);
            }

            if (top_right_lines.Count > 0)
            {
                top_right_line = getBigLine(top_right_lines);
                CvInvoke.ArrowedLine(img, top_right_line.line.P1, top_right_line.line.P2, new Bgr(Color.White).MCvScalar, 1);
            }


            if (middle_left_lines.Count > 0)
            {
                middle_left_line = getBigLine(middle_left_lines);
                CvInvoke.ArrowedLine(img, middle_left_line.line.P1, middle_left_line.line.P2, new Bgr(Color.White).MCvScalar, 1);
            }

            if (middle_middle_lines.Count > 0)
            {
                middle_middle_line = getBigLine(middle_middle_lines);
                CvInvoke.ArrowedLine(img, middle_middle_line.line.P1, middle_middle_line.line.P2, new Bgr(Color.White).MCvScalar, 1);
            }

            if (middle_right_lines.Count > 0)
            {
                middle_right_line = getBigLine(middle_right_lines);
                CvInvoke.ArrowedLine(img, middle_right_line.line.P1, middle_right_line.line.P2, new Bgr(Color.White).MCvScalar, 1);
            }


            if (bottom_left_lines.Count > 0)
            {
                bottom_left_line = getBigLine(bottom_left_lines);
                CvInvoke.ArrowedLine(img, bottom_left_line.line.P1, bottom_left_line.line.P2, new Bgr(Color.White).MCvScalar, 1);
            }
            if (bottom_middle_lines.Count > 0)
            {
                bottom_middle_line = getBigLine(bottom_middle_lines);
                CvInvoke.ArrowedLine(img, bottom_middle_line.line.P1, bottom_middle_line.line.P2, new Bgr(Color.White).MCvScalar, 1);
            }

            if (bottom_right_lines.Count > 0)
            {
                bottom_right_line = getBigLine(bottom_right_lines);
                CvInvoke.ArrowedLine(img, bottom_right_line.line.P1, bottom_right_line.line.P2, new Bgr(Color.White).MCvScalar, 1);
            }
            //WriteFeatureToCSV();
            //CvInvoke.NamedWindow("Motion Tracking");
            // CvInvoke.Imshow("Motion Tracking", img.Resize(200,200,Inter.Cubic));
            //CvInvoke.Imwrite("C:\\Users\\Antivirus\\Desktop\\of\\Frames.png",img);
            //CvInvoke.Imwrite("C:\\Users\\Antivirus\\Desktop\\of\\opticalflow" + (frameNumber - 1) + "-" + (frameNumber) + ".png", img);
            return(img);
        }
Example #5
0
        //This method checks the location of the points on the grid and displays markers if it exceeds these points
        //it returns a value indicating if the current feed should be switched or not
        public int checkBounds(int curr_x, int curr_y, Mat overlay)
        {
            //the overlay grid gives us the size of the video so that we can determine where the limits are
            //Overlay.cols = number of x-colums (pixels) in the image
            //Overlay.rows = number of y-rows (pixels) in the image
            int xLimit = overlay.Cols;
            int yLimit = overlay.Rows;

            if (curr_x < 0 || curr_x > xLimit)
            {
                LimitExceededLong = "Longitude offscreen: (" + curr_x + "," + curr_y + ")";
                longitudeOutOfRangeOverlayMessage = LimitExceededLong;      //write this message to the UI class
                CvInvoke.PutText(overlayGrid, LimitExceededLong, new Point(10, 20), Emgu.CV.CvEnum.FontFace.HersheyComplexSmall, 0.5, new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.EightConnected, false);
            }
            else
            {
                longitudeOutOfRangeOverlayMessage = "";     //clear out of bounds message
            }
            if (curr_y < 0 || curr_y > yLimit)
            {
                LimitExceededLat = "";
                LimitExceededLat = "Latitude offscreen: (" + curr_x + "," + curr_y + ")";
                latitudeOutOfRangeOverlayMessage = LimitExceededLat;        //write this message to the UI class
                CvInvoke.PutText(overlayGrid, LimitExceededLat, new Point(10, 30), Emgu.CV.CvEnum.FontFace.HersheyComplexSmall, 0.5, new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.EightConnected, false);
            }
            else
            {
                latitudeOutOfRangeOverlayMessage = "";          //clear out of bounds message
            }

            //systematic check to determine where the offscreen point is so that we can draw an arrow to it

            /*
             *      The letters correspond to the zones we check in order shown
             *      The top-left corner is the origin of the video frame
             *      _A_|________D_____|_F_
             *       B |	onscreen  | G
             *      __ |_____________ |__
             *       C |		E	  | H
             *
             *       Drawing arrow:
             *       arrowedLine(InputOutputArray img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0, double tipLength=0.1)
             *
             */


            if (curr_x < 0)     //narrow to A,B,C
            {
                if (curr_y < 0)
                {
                    //draw line to corner of A
                    CvInvoke.ArrowedLine(overlayGrid, new Point(50, 50), new Point(0, 0), new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, 0, 0.1);
                    CvInvoke.PutText(overlayGrid, "Offscreen here", new Point(40, 40), Emgu.CV.CvEnum.FontFace.HersheyComplexSmall, 0.5, new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, false);
                    latitudeOutOfRangeOverlayMessage  = "Latitude Out Of Range: " + curr_y.ToString();
                    longitudeOutOfRangeOverlayMessage = "Longitude Out Of Range:" + curr_x.ToString();

                    //send back command to switch left
                    return(GO_CAM_LEFT);
                }
                else if (curr_y > 0 && curr_y < yLimit)
                {
                    //draw line to the y-part of B
                    CvInvoke.ArrowedLine(overlayGrid, new Point(50, curr_y), new Point(0, curr_y), new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, 0, 0.1);
                    CvInvoke.PutText(overlayGrid, "Offscreen here", new Point(40, curr_y), Emgu.CV.CvEnum.FontFace.HersheyComplexSmall, 0.5, new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, false);
                    latitudeOutOfRangeOverlayMessage  = "Latitude in range - Switch Cam Left";
                    longitudeOutOfRangeOverlayMessage = "Longitude " + curr_x.ToString() + " OOR - Switch Cam Left";

                    //send back command to switch left
                    return(GO_CAM_LEFT);
                }
                else if (curr_y > yLimit)
                {
                    //draw line to point of C
                    CvInvoke.ArrowedLine(overlayGrid, new Point(0, yLimit), new Point(50, yLimit - 50), new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, 0, 0.1);
                    CvInvoke.PutText(overlayGrid, "Offscreen here", new Point(40, yLimit - 40), Emgu.CV.CvEnum.FontFace.HersheyComplexSmall, 0.5, new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, false);
                    latitudeOutOfRangeOverlayMessage  = "Latitude Out Of Range: " + curr_y.ToString();
                    longitudeOutOfRangeOverlayMessage = "Longitude Out Of Range:" + curr_x.ToString();

                    //send back command to switch left
                    return(GO_CAM_LEFT);
                }
            }
            else if (curr_x > 0 && curr_x < xLimit)     //narrow to D or E
            {
                if (curr_y < 0)
                {
                    //draw D
                    CvInvoke.ArrowedLine(overlayGrid, new Point(curr_x, 50), new Point(curr_x, 0), new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, 0, 0.1);
                    CvInvoke.PutText(overlayGrid, "Offscreen here", new Point(curr_x, 40), Emgu.CV.CvEnum.FontFace.HersheyComplexSmall, 0.5, new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, false);
                    latitudeOutOfRangeOverlayMessage  = "Latitude out of range";
                    longitudeOutOfRangeOverlayMessage = "Longitude " + curr_y.ToString() + " in range above";

                    //send back command to stay on current frame
                    return(STAY_CAM_CURRENT);
                }
                else if (curr_y > yLimit)
                {
                    //draw E
                    CvInvoke.ArrowedLine(overlayGrid, new Point(curr_x, yLimit - 60), new Point(curr_x, yLimit), new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, 0, 0.1);
                    CvInvoke.PutText(overlayGrid, "Offscreen here", new Point(curr_x, yLimit - 40), Emgu.CV.CvEnum.FontFace.HersheyComplexSmall, 0.5, new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, false);
                    latitudeOutOfRangeOverlayMessage  = "Latitude out of range";
                    longitudeOutOfRangeOverlayMessage = "Longitude " + curr_y.ToString() + " in range below";

                    //send back command to stay on current frame
                    return(STAY_CAM_CURRENT);
                }
            }
            else if (curr_x > xLimit)                   //narrow to F,G,H
            {
                if (curr_y < 0)
                {
                    //draw F
                    CvInvoke.ArrowedLine(overlayGrid, new Point(xLimit - 80, 50), new Point(xLimit, 0), new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, 0, 0.1);
                    CvInvoke.PutText(overlayGrid, "Offscreen here", new Point(xLimit - 100, 50), Emgu.CV.CvEnum.FontFace.HersheyComplexSmall, 0.5, new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, false);
                    latitudeOutOfRangeOverlayMessage  = "Latitude Out Of Range: " + curr_y.ToString();
                    longitudeOutOfRangeOverlayMessage = "Longitude Out Of Range:" + curr_x.ToString();

                    //send back command to switch right
                    return(GO_CAM_RIGHT);
                }
                else if (curr_y > 0 && curr_y < yLimit)
                {
                    //draw G
                    CvInvoke.ArrowedLine(overlayGrid, new Point(xLimit - 80, curr_y), new Point(xLimit, curr_y), new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, 0, 0.1);
                    CvInvoke.PutText(overlayGrid, "Offscreen here", new Point(xLimit - 100, curr_y), Emgu.CV.CvEnum.FontFace.HersheyComplexSmall, 0.5, new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, false);
                    latitudeOutOfRangeOverlayMessage  = "Latitude in range - Switch Cam Right";
                    longitudeOutOfRangeOverlayMessage = "Longitude " + curr_x.ToString() + " OOR - Switch Cam Right";

                    //send back command to switch right
                    return(GO_CAM_RIGHT);
                }
                else if (curr_y > yLimit)
                {
                    //draw H
                    CvInvoke.ArrowedLine(overlayGrid, new Point(xLimit - 80, yLimit - 80), new Point(xLimit, yLimit), new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, 0, 0.1);
                    CvInvoke.PutText(overlayGrid, "Offscreen here", new Point(xLimit - 100, yLimit - 40), Emgu.CV.CvEnum.FontFace.HersheyComplexSmall, 0.5, new MCvScalar(255, 0, 0), 1, Emgu.CV.CvEnum.LineType.AntiAlias, false);
                    latitudeOutOfRangeOverlayMessage  = "Latitude Out Of Range: " + curr_y.ToString();
                    longitudeOutOfRangeOverlayMessage = "Longitude Out Of Range:" + curr_x.ToString();

                    //send back command to switch right
                    return(GO_CAM_RIGHT);
                }
                else
                {
                    //clear the out of range messages since nothing was out of range
                    longitudeOutOfRangeOverlayMessage = "";
                    latitudeOutOfRangeOverlayMessage  = "";
                    return(STAY_CAM_CURRENT);
                }
            }
            return(STAY_CAM_CURRENT);      //not out of bounds anywhere
        }
Example #6
0
        /// <summary>
        /// 创建Seal图像并填入指定图像
        /// </summary>
        /// <param name="Result"></param>
        /// <param name="ImgSize"></param>
        /// <param name="Template"></param>
        /// <param name="ImgFilePath"></param>
        /// <param name="charStr"></param>
        /// <param name="direction"></param>
        public static void CreateImg(ref Mat Result, Size ImgSize, DataTable Template, string ImgFilePath, string charStr, Direction direction)
        {
            //异常检测
            if (Template.Rows.Count <= 0 || Template.Columns.Count <= 0)
            {
                return;
            }
            //确定基本图像大小
            int width  = ImgSize.Width;  //Columns
            int height = ImgSize.Height; //Rows

            //创建图像
            Result = new Mat(new Size(ImgSize.Width * Template.Columns.Count, ImgSize.Height * Template.Rows.Count), DepthType.Cv8U, 3);//大小,深度 - 8u,通道 - 3
            //获取ImgFileList
            List <FileInfo> ImgFile = GetFile(ImgFilePath, ProgramData.ImgSuffix);

            //Result追加图像
            string id   = ""; //ID编号
            string name = ""; //文件名

            for (int i = 0; i < Template.Rows.Count; i++)
            {
                for (int j = 0; j < Template.Columns.Count; j++)
                {
                    if (charStr == ProgramData.SealStr)
                    {
                        id = Template.Rows[i][j].ToString().PadLeft(3, '0');//获取ID
                        if (id == "000" || string.IsNullOrEmpty(id))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        id = Template.Rows[i][j].ToString();//获取ID
                        if (id == "0" || string.IsNullOrEmpty(id))
                        {
                            continue;
                        }
                    }
                    //拼接文件名
                    name = charStr + id;
                    //检测文件是否存在
                    FileInfo fileInfo = ImgFile.Where(o => o.Name.Contains(name)).FirstOrDefault();
                    if (fileInfo == null)
                    {
                        CvInvoke.PutText(Result, "Lost:" + name, new Point(width * j, height * i + height / 2), FontFace.HersheySimplex, 2, new MCvScalar(255, 255, 0), 2);//追加文字lost+文件名
                    }
                    else//图片存在
                    {
                        //判断文件是否被移除
                        if (File.Exists(fileInfo.FullName))
                        {
                            Mat Img = new Mat(fileInfo.FullName, ImreadModes.Color);                                                //读取文件
                            //CvInvoke.Imshow("Result"+ id, Img);
                            Rectangle rectangle = new Rectangle(new Point(width * j, height * i), new Size(Img.Width, Img.Height)); //创建放置区域,点和大小
                            Mat       figureTo  = new Mat(Result, rectangle);                                                       //定义指向区域
                            Img.CopyTo(figureTo);                                                                                   //将图像粘贴过去
                        }
                        else
                        {
                            CvInvoke.PutText(Result, "Lost:" + fileInfo.Name, new Point(width * i + width / 2, height * j + height / 2), FontFace.HersheySimplex, 10, new MCvScalar(255, 255, 0), 5);//追加文字lost+文件名
                        }
                    }
                }
            }
            //绘制网格线
            for (int i = 0; i <= Template.Rows.Count; i++)//横线 Rows
            {
                CvInvoke.Line(Result, new Point(0, height * i), new Point(width * Template.Columns.Count, height * i), new MCvScalar(0, 255, 0), 2, LineType.EightConnected);
            }
            for (int j = 0; j <= Template.Columns.Count; j++)//竖线 Columns
            {
                CvInvoke.Line(Result, new Point(width * j, 0), new Point(width * j, height * Template.Rows.Count), new MCvScalar(0, 255, 0), 2, LineType.EightConnected);
            }
            //绘制方向
            if (ProgramData.DirectType == 0)
            {
                //绘制三角形 方式0
                VectorOfPoint pointsArray = new VectorOfPoint();
                Point[]       points      = new Point[3];
                switch (direction)
                {
                case Direction.TopLeft:
                    points[0] = new Point(0, 0);
                    points[1] = new Point(ProgramData.ArrowSize.Width, 0);
                    points[2] = new Point(0, ProgramData.ArrowSize.Height);
                    pointsArray.Push(points);
                    CvInvoke.FillConvexPoly(Result, pointsArray, new MCvScalar(0, 0, 255), LineType.EightConnected);
                    break;

                case Direction.BottomLeft:
                    points[0] = new Point(0, Result.Height - ProgramData.ArrowSize.Height);
                    points[1] = new Point(0, Result.Height);
                    points[2] = new Point(ProgramData.ArrowSize.Width, Result.Height);
                    pointsArray.Push(points);
                    CvInvoke.FillConvexPoly(Result, pointsArray, new MCvScalar(0, 0, 255), LineType.EightConnected);
                    break;

                case Direction.TopRigth:
                    points[0] = new Point(Result.Width - ProgramData.ArrowSize.Width, 0);
                    points[1] = new Point(Result.Width, 0);
                    points[2] = new Point(Result.Width, ProgramData.ArrowSize.Height);
                    pointsArray.Push(points);
                    CvInvoke.FillConvexPoly(Result, pointsArray, new MCvScalar(0, 0, 255), LineType.EightConnected);
                    break;

                case Direction.BottomRight:
                    points[0] = new Point(Result.Width, Result.Height - ProgramData.ArrowSize.Height);
                    points[1] = new Point(Result.Width, Result.Height);
                    points[2] = new Point(Result.Width - ProgramData.ArrowSize.Width, Result.Height);
                    pointsArray.Push(points);
                    CvInvoke.FillConvexPoly(Result, pointsArray, new MCvScalar(0, 0, 255), LineType.EightConnected);
                    break;

                default:
                    break;
                }
            }
            else if (ProgramData.DirectType == 1)
            {
                //绘制箭头 方式1
                switch (direction)
                {
                case Direction.TopLeft:
                    CvInvoke.ArrowedLine(Result, new Point(ProgramData.ArrowSize), new Point(0, 0), new MCvScalar(0, 0, 255), 2, LineType.EightConnected);
                    break;

                case Direction.BottomLeft:
                    CvInvoke.ArrowedLine(Result, new Point(ProgramData.ArrowSize.Width, Result.Height - ProgramData.ArrowSize.Height), new Point(0, Result.Height), new MCvScalar(0, 0, 255), 5, LineType.EightConnected);
                    break;

                case Direction.TopRigth:
                    CvInvoke.ArrowedLine(Result, new Point(Result.Width - ProgramData.ArrowSize.Width, ProgramData.ArrowSize.Height), new Point(Result.Width, 0), new MCvScalar(0, 0, 255), 5, LineType.EightConnected);
                    break;

                case Direction.BottomRight:
                    CvInvoke.ArrowedLine(Result, new Point(Result.Width - ProgramData.ArrowSize.Width, Result.Height - ProgramData.ArrowSize.Height), new Point(Result.Width, Result.Height), new MCvScalar(0, 0, 255), 5, LineType.EightConnected);
                    break;

                default:
                    break;
                }
            }
            GC.Collect();//回收资源
        }