private static Gray <byte>[,] QuantizeOrientations(Gray <int>[,] orientDegImg)
        {
            var quantizedUnfilteredOrient = new Gray <byte> [orientDegImg.Height(), orientDegImg.Width()];

            using (var uOrientDegImg = orientDegImg.Lock())
                using (var uQuantizedUnfilteredOrient = quantizedUnfilteredOrient.Lock())
                {
                    int * orientDegImgPtr         = (int *)uOrientDegImg.ImageData;
                    byte *qOrinetUnfilteredPtr    = (byte *)uQuantizedUnfilteredOrient.ImageData;
                    int   qOrinetUnfilteredStride = uQuantizedUnfilteredOrient.Stride;

                    int imgWidth  = uOrientDegImg.Width;
                    int imgHeight = uOrientDegImg.Height;

                    for (int j = 0; j < imgHeight; j++)
                    {
                        for (int i = 0; i < imgWidth; i++)
                        {
                            int angle = orientDegImgPtr[i];
                            qOrinetUnfilteredPtr[i] = AngleQuantizationTable[angle]; //[0-360] -> [...] -> [0-7] (for mapping see "CalculateAngleQuantizationTable()")
                        }

                        orientDegImgPtr      += imgWidth; //<Gray<int>> is always alligned
                        qOrinetUnfilteredPtr += qOrinetUnfilteredStride;
                    }
                }

            //quantizedUnfilteredOrient.Mul(36).Save("quantizedUnfilteredImg.bmp");
            return(quantizedUnfilteredOrient);
        }
示例#2
0
        /// <summary>
        /// Given a specific image, eliminate the redunant features (i.e. remove any feature that is outside the green circle
        /// </summary>
        /// <param name="reps">current template pyrimid to be checked</param>
        /// <param name="image">the video image, served as a size comparator</param>
        /// /// <returns>nothing.</returns>
        public static TemplatePyramid validateFeatures(TemplatePyramid reps, Gray <byte>[,] image)
        {
            List <Feature> temp;
            int            shortSide = (image.Width() < image.Height()) ? image.Width() : image.Height();

            foreach (Template t in reps.Templates)
            {
                temp = t.Features.ToList();
                for (int i = 0; i < t.Features.Count(); i++)
                {
                    int p = (t.Features[i].X + t.BoundingRect.X - image.Width() / 2) * (t.Features[i].X + t.BoundingRect.X - image.Width() / 2) + (t.Features[i].Y + t.BoundingRect.Y - image.Height() / 2) * (t.Features[i].Y + t.BoundingRect.Y - image.Height() / 2);
                    //Console.WriteLine(p + "    " + t.Features[i].X + "  " + t.Features[i].Y);
                    if (p > ((shortSide / 2) * (shortSide / 2)))
                    {
                        //Console.WriteLine(p + "asdf gsfdgafhsdgsdfhsdhsdhsd    " + t.Features[i].X + "  " + t.Features[i].Y);
                        temp.Remove(t.Features[i]);
                    }
                }

                t.Features = temp.ToArray();

                //Console.WriteLine("NUM of features: " + t.Features.Count());

                //GC.Collect();
            }
            return(reps);
        }
示例#3
0
        /// <summary>
        /// build template List from a Gray image
        /// </summary>
        /// <param name="image">input image</param>
        /// <param name="buildXMLTemplateFile">true to build a xml file with current templates</param>
        /// <param name="angles">the number of angles, default to 360</param>
        /// <param name="sizes">number of sizes, default to 1</param>
        /// <param name="minRatio">The ratio of smallest size to original, default to 0.6</param>
        /// <param name="maxFeaturesPerLevel">the array of maximum features per pyrimid level, default to 200 in DEFAULT_MAX_FEATURES_PER_LEVEL from ImageTemplatePyramid.cs:56,
        ///                                     increase to increase the precision in expense of detection time-delay</param>
        /// <param name="userFunc">Input User Function for customization and diversity</param>
        /// <returns>List of templates.</returns>
        public static List <TemplatePyramid> buildTemplate(Gray <byte>[,] image, int Width, int Height, bool buildXMLTemplateFile = false, int angles = 360, int sizes = 1, float minRatio = 0.6f, int[] maxFeaturesPerLevel = null, Func <TemplatePyramid, Gray <byte> [, ], TemplatePyramid> userFunc = null)
        {
            List <TemplatePyramid> retList = new List <TemplatePyramid>();
            float Ratio = 1;

            Gray <byte>[,] tempIMG;
            rotateLoad(retList, image, angles, Width, Height, false, userFunc: validateFeatures);
            for (int i = 0; i < sizes - 1; i++)
            {
                Ratio -= (float)(1 - minRatio) / sizes;
                int width  = (int)(image.Width() * Ratio);
                int height = (int)(image.Height() * Ratio);

                DotImaging.Primitives2D.Size Nsize = new DotImaging.Primitives2D.Size(width, height);
                tempIMG = ResizeExtensions_Gray.Resize(image, Nsize, Accord.Extensions.Imaging.InterpolationMode.NearestNeighbor);

                rotateLoad(retList, tempIMG, angles, Width, Height, false, maxFeaturesPerLevel, image.ToString(), userFunc: userFunc);
            }
            if (buildXMLTemplateFile)
            {
                XMLTemplateSerializer <ImageTemplatePyramid <ImageTemplate>, ImageTemplate> .ToFile(retList,
                                                                                                    Path.Combine(Directory.GetParent(Directory.GetCurrentDirectory()).FullName, "Resources", "template" + ".xml"));
            }

            return(retList);
        }
        /// <summary>
        /// Creates linear response maps.
        /// </summary>
        /// <param name="orientationDegImg">Orientation image (in degrees).</param>
        /// <param name="neigborhood">Spread neighborhood size.</param>
        public LinearizedMaps(Gray <int>[,] orientationDegImg, int neigborhood)
        {
            this.NeigborhoodSize = neigborhood;
            this.ImageSize       = orientationDegImg.Size();

            this.LinearMapSize  = new Size(orientationDegImg.Width() / neigborhood, orientationDegImg.Height() / neigborhood);
            this.ImageValidSize = new Size(this.LinearMapSize.Width * neigborhood, this.LinearMapSize.Height * neigborhood);

            this.LinearMaps = calculate(orientationDegImg);
        }
        /// <summary>
        /// Computes gradient orientations from the color image. Orientation from the channel which has the maximum gradient magnitude is taken as the orientation for a location.
        /// </summary>
        /// <param name="frame">Image.</param>
        /// <param name="magnitudeSqrImage">Squared magnitude image.</param>
        /// <param name="minValidMagnitude">Minimal valid magnitude.</param>
        /// <returns>Orientation image (angles are in degrees).</returns>
        public unsafe static Gray <int>[,] Compute(Gray <byte>[,] frame, out Gray <int>[,] magnitudeSqrImage, int minValidMagnitude)
        {
            var minSqrMagnitude = minValidMagnitude * minValidMagnitude;

            var orientationImage   = new Gray <int> [frame.Height(), frame.Width()];
            var _magnitudeSqrImage = orientationImage.CopyBlank();

            using (var uFrame = frame.Lock())
            {
                ParallelLauncher.Launch(thread =>
                {
                    computeGray(thread, (byte *)uFrame.ImageData, uFrame.Stride, orientationImage, _magnitudeSqrImage, minSqrMagnitude);
                },
                                        frame.Width() - 2 * kernelRadius, frame.Height() - 2 * kernelRadius);
            }

            magnitudeSqrImage = _magnitudeSqrImage;
            return(orientationImage);
        }
示例#6
0
        /// <summary>
        /// rotate the image for  <param name="angles"> angles and load them into the <param name="retList"> List.
        /// </summary>
        /// <param name="retList">the list that mean to be loaded with the new templates, create a new one if null is passed in</param>
        /// <param name="image">input image</param>
        /// <param name="angles">the number of angles</param>
        /// <param name="Width">The Width that the orginal image is cropped into, must be less than image.Width()</param>
        /// <param name="Height">The Height that the orginal image is cropped into, must be less than image.Height()</param>
        /// <param name="buildXMLTemplateFile">true to build a xml file with current templates</param>
        /// <param name="maxFeaturesPerLevel">the array of maximum features per pyrimid level, default to 200 in DEFAULT_MAX_FEATURES_PER_LEVEL from ImageTemplatePyramid.cs:56,
        ///                                     increase to increase the precision in expense of detection time-delay</param>
        /// <param name="userFunc">Input User Function for customization and diversity</param>
        /// <returns>nothing.</returns>
        private static void rotateLoad(List <TemplatePyramid> retList, Gray <byte>[,] image, int angles, int Width, int Height, bool buildXMLTemplateFile = false, int[] maxFeaturesPerLevel = null, string name = "DefaultTemplate", Func <TemplatePyramid, Gray <byte> [, ], TemplatePyramid> userFunc = null)
        {
            string resourceDir = Path.Combine(Directory.GetParent(Directory.GetCurrentDirectory()).FullName, "Resources");

            retList = (retList == null ? new List <TemplatePyramid>() : retList);
            Width   = (Width > image.Width() ? image.Width() : Width);
            Height  = (Height > image.Height() ? image.Height() : Height);
            //userFunc = (userFunc != null) ? userFunc : (inputList, inputImage) => inputList;

            for (int i = 0; i < angles; i++)
            {
                float  ImageAngle = (float)i * 360 / angles;
                Bitmap bitmap     = image.ToBitmap();

                Bitmap   returnBitmap = new Bitmap(Width, Height);
                Graphics graphics     = Graphics.FromImage(returnBitmap);
                graphics.TranslateTransform((float)Width / 2, (float)Height / 2);
                graphics.RotateTransform(ImageAngle);
                graphics.TranslateTransform(-(float)Width / 2, -(float)Height / 2);
                graphics.DrawImage(bitmap, new System.Drawing.Point(-(image.Width() - Width) / 2, -(image.Height() - Height) / 2));
                bitmap.Dispose();
                returnBitmap.Save("TP.bmp");
                Console.WriteLine(" angle " + ImageAngle);
                Gray <byte>[,] preparedBWImage = ImageIO.LoadGray("TP.bmp").Clone();

                try
                {
                    TemplatePyramid newTemp = TemplatePyramid.CreatePyramidFromPreparedBWImage(
                        preparedBWImage, name, ImageAngle, maxNumberOfFeaturesPerLevel: maxFeaturesPerLevel);
                    if (userFunc != null)
                    {
                        newTemp = userFunc(newTemp, image);
                    }
                    retList.Add(newTemp);
                }
                catch (Exception)
                { }
            }
            if (buildXMLTemplateFile)
            {
                XMLTemplateSerializer <ImageTemplatePyramid <ImageTemplate>, ImageTemplate> .ToFile(retList, Path.Combine(resourceDir, "template" + ".xml"));
            }
        }
        /// <summary>
        /// Creates integral image.
        /// </summary>
        /// <param name="img">Image.</param>
        /// <returns>Integral image.</returns>
        public static Gray <double>[,] MakeIntegral(this Gray <double>[,] img)
        {
            var dstImg = new Gray <double> [img.Height() + 1, img.Width() + 1];

            using (var uImg = img.Lock())
                using (var uDstImg = dstImg.Lock())
                {
                    makeIntegral_Double(uImg, uDstImg);
                }

            return(dstImg);
        }
        private static IList <PointF> findContour(Gray <byte>[,] templateImg)
        {
            var contour = templateImg.FindContour(minGradientStrength: 150).Select(x => (PointF)x).ToList();

            /*********** cut bottom border and shift contour beginning to the first non-border point ***************/
            int firstIdx = -1;
            int lastIdx  = -1;

            for (int i = 0; i < contour.Count; i++)
            {
                if (contour[i].Y == (templateImg.Height() - 1))
                {
                    if (firstIdx == -1)
                    {
                        firstIdx = i;
                    }
                    lastIdx = i;
                }
            }

            //return contour;
            return(new CircularList <PointF>(contour).GetRange(lastIdx, contour.Count - (lastIdx - firstIdx + 1)));
        }