/// <summary>
 /// Creates a traffic sign
 /// </summary>
 /// <param name="image"> image of the sign </param>
 /// <param name="name"> name of the sign </param>
 public TrafficSign(Image <Bgr, byte> image, string name)
 {
     ImageOriginal = image;
     Emgu.CV.CvEnum.Inter inter = image.Height > SignHeight ? Emgu.CV.CvEnum.Inter.Area : Emgu.CV.CvEnum.Inter.Cubic;
     ImageGray = image.Convert <Gray, byte>().Resize(int.MaxValue, SignHeight, inter, true);
     Name      = name;
     InitMatcher();
     IsKnownSign = true;
 }
 /// <summary>
 /// Creates a traffic sign
 /// </summary>
 /// <param name="Image"> image of the sign </param>
 public TrafficSign(Image <Bgr, byte> Image)
 {
     ImageOriginal = Image;
     Emgu.CV.CvEnum.Inter inter = Image.Height > SignHeight ? Emgu.CV.CvEnum.Inter.Area : Emgu.CV.CvEnum.Inter.Cubic;
     ImageGray   = Image.Convert <Gray, byte>().Resize(int.MaxValue, SignHeight, inter, true);
     Name        = null;
     matcher     = null;
     IsKnownSign = false;
 }
Exemple #3
0
        // Divides area of real mozaic into blocks, separated by frame walls.
        // If whole number of blocks doesn't fit into given area its margins are cropped.
        // Finally, given image is resized so that its every pixel corresponds to a color block.
        // Color of each block is interpolated from its neighbourhood according to given interpolation method.
        //
        // If image cannot be fragmented (e.g. when even one block won't fit real mozaic), null is returned.
        public static FragmentationResult FragmentImage(
            Image <Bgr, byte> image,
            SizeF realSize,
            double blockSize, double frameSize, // size of frame between blocks
            Emgu.CV.CvEnum.Inter interpolationMethod = Emgu.CV.CvEnum.Inter.Cubic
            )
        {
            // Compute how many blocks will fit into image, taking into account spacing between them
            // Number of frame sides is equal to number of blocks + 1, thats why frameSize is substracted from real size
            double blockWithFrame = blockSize + frameSize;
            int    rows           = (int)((realSize.Height - frameSize) / blockWithFrame);
            int    cols           = (int)((realSize.Width - frameSize) / blockWithFrame);

            if (rows == 0 || cols == 0)
            {
                // Not even one block would fit
                return(null);
            }

            // Actual size of mozaic
            double actualHeight = rows * blockSize + (rows + 1) * frameSize;
            double actualWidth  = cols * blockSize + (cols + 1) * frameSize;

            // Amount of image which needs to be cut from each side
            // It will also define top-left of mozaic on image
            double marginTop  = (realSize.Height - frameSize - rows * blockWithFrame) / 2;
            double marginLeft = (realSize.Width - frameSize - cols * blockWithFrame) / 2;

            // Relative values (in range [0-1])
            double topRelative    = marginTop / realSize.Height;
            double leftRelative   = marginLeft / realSize.Width;
            double heightRelative = actualHeight / realSize.Height;
            double widthRelative  = actualWidth / realSize.Width;

            int topPixel    = (int)(topRelative * image.Rows);
            int leftPixel   = (int)(leftRelative * image.Cols);
            int heightPixel = (int)(heightRelative * image.Rows);
            int widthPixel  = (int)(widthRelative * image.Cols);

            // Crop image accroding to computed pixel sizes
            var cropped = image.GetSubRect(new Rectangle(
                                               leftPixel, topPixel,
                                               widthPixel, heightPixel
                                               ));

            // Simplest way to pick color for each block will be to up-/downscale image so that each pixel will correspond to one block
            var resized = image.Resize(cols, rows, interpolationMethod);

            return(new FragmentationResult()
            {
                Blocks = resized,
                MarginTop = marginTop,
                MarginLeft = marginLeft
            });
        }
Exemple #4
0
        private bool FragmentImage(Image <Bgr, byte> i)
        {
            Sizes sizes = ReadSizes();

            if (sizes.IsInvalid())
            {
                return(false);
            }

            Emgu.CV.CvEnum.Inter interpolationMethod = (Emgu.CV.CvEnum.Inter)interpolationMethodInput.SelectedItem;

            FragmentationResult result = Fragmenter.FragmentImage(
                i,
                new SizeF((float)sizes.realWidth, (float)sizes.realHeight),
                sizes.blockSize, sizes.frameSize,
                interpolationMethod
                );

            fragmentedImage = result.Blocks;
            return(true);
        }
        /// <summary>
        /// Draws the recognised signs
        /// </summary>
        /// <param name="src"> original image to draw on </param>
        /// <param name="matches"> traffic sign matches </param>
        /// <param name="rawCandidates"> raw candidates </param>
        /// <returns> image with signs </returns>
        private Image <Bgr, byte> DrawSigns(Image <Bgr, byte> src, List <TrafficSignMatch> matches, List <TrafficSign> rawCandidates)
        {
            Image <Bgr, byte> result = src.Copy();

            rawCandidates.ForEach(candidate =>
            {
                // Draw candidates
                result.Draw(candidate.BoundingBoxInScene, new Bgr(255, 20, 20), 1);
            });
            matches.ForEach(match =>
            {
                // Draw matches bounding boxes
                result.Draw(match.Candidate.BoundingBoxInScene, new Bgr(50, 255, 50), 3);
                Image <Bgr, byte> signToDraw = match.KnownSign.ImageOriginal.Clone();
                Emgu.CV.CvEnum.Inter inter   = match.Candidate.BoundingBoxInScene.Width > signToDraw.Width ? Emgu.CV.CvEnum.Inter.Area : Emgu.CV.CvEnum.Inter.Cubic;
                signToDraw = signToDraw.Resize(match.Candidate.BoundingBoxInScene.Width, int.MaxValue, inter, true);

                if (match.Candidate.BoundingBoxInScene.Bottom + match.KnownSign.ImageOriginal.Height > src.Height)
                {
                    // Draw sign above candidate
                    Point p = match.Candidate.BoundingBoxInScene.Location;
                    p.Offset(0, -signToDraw.Size.Height);
                    result.ROI = new Rectangle(p, signToDraw.Size);
                }
                else
                {
                    // Draw sign below candidate
                    Point p = match.Candidate.BoundingBoxInScene.Location;
                    p.Offset(0, match.Candidate.BoundingBoxInScene.Size.Height);
                    result.ROI = new Rectangle(p, signToDraw.Size);
                }
                signToDraw.CopyTo(result);
                result.ROI = Rectangle.Empty;
            });
            return(result);
        }
Exemple #6
0
        public static Image <Bgr, byte> ResizeImage(Image <Bgr, byte> srcImg, int width, int height, Emgu.CV.CvEnum.Inter interpolationType)
        {
            if (width == 0 || height == 0)
            {
                return(null);
            }

            Image <Bgr, byte> imgScale = new Image <Bgr, byte>(width, height);

            CvInvoke.Resize(srcImg, imgScale, new System.Drawing.Size(width, height), 0, 0, interpolationType);
            return(imgScale);
        }
Exemple #7
0
        /// <summary>
        /// Computes the homography between 2 given rectangles and warps the source image.
        /// </summary>
        /// <param name="src"> Source Image </param>
        /// <param name="srcPoints"> Source rectangle, clockwise point array </param>
        /// <param name="resPoints"> Destination rectangle, clockwise point array </param>
        /// <param name="resSize"> Size of the destination image </param>
        /// <param name="interpolation"> Interpolation type </param>
        /// <returns> Destination Image </returns>
        public static Image <Bgr, byte> Render(Image <Bgr, byte> src, Point[] srcPoints, Point[] resPoints, Size resSize, Emgu.CV.CvEnum.Inter interpolation)
        {
            Image <Bgr, byte> buffer = new Image <Bgr, byte>(src.Size);

            if (srcPoints.Length != 4 || resPoints.Length != 4)
            {
                return(src);
            }
            float[,] roi =
            {
                { srcPoints[0].X, srcPoints[0].Y },
                { srcPoints[1].X, srcPoints[1].Y },
                { srcPoints[2].X, srcPoints[2].Y },
                { srcPoints[3].X, srcPoints[3].Y }
            };
            Matrix <float> sourceMat = new Matrix <float>(roi);

            float[,] target =
            {
                { resPoints[0].X, resPoints[0].Y },
                { resPoints[1].X, resPoints[1].Y },
                { resPoints[2].X, resPoints[2].Y },
                { resPoints[3].X, resPoints[3].Y }
            };
            Matrix <float> targetMat = new Matrix <float>(target);
            Mat            transform = CvInvoke.GetPerspectiveTransform(sourceMat, targetMat);

            CvInvoke.WarpPerspective(src, buffer, transform, resSize, interpolation);
            return(buffer);
        }