예제 #1
0
        /// <summary>
        /// Returns the distance from the target color histogram the given pixel array is
        /// </summary>
        /// <param name="pixelArray">The pixel array of the bitmap to get the distance of</param>
        /// <param name="bitmapWidth">The width of the bitmap</param>
        /// <param name="bitmapHeight">The height of the bitmap</param>
        /// <param name="stride">The number of bytes per row</param>
        /// <param name="targetColor">The histogram of the color of the target object</param>
        /// <returns>The minimum distance a subrect of the image is from the target histogram</returns>
        private static double GetColorDistance(byte[] pixelArray, int bitmapWidth, int bitmapHeight, int stride, double[] targetColor)
        {
            var colorDistancePixelArray = (byte[])pixelArray.Clone();
            var pixelArrayLock          = new object();

            // Threshold the image for possible areas where the object is
            Parallel.ForEach(ExtensionMethods.SteppedRange(0, bitmapWidth, 8), column =>
            {
                Parallel.ForEach(ExtensionMethods.SteppedRange(0, bitmapHeight, 8), row =>
                {
                    int width             = Math.Min(8, bitmapWidth - column);
                    int height            = Math.Min(8, bitmapHeight - row);
                    var croppedPixelArray = pixelArray.CropPixelArray(column, row, width, height, stride);
                    var colorBins         = ColorClassifier.GetColorBins(croppedPixelArray, true);
                    var distance          = ColorClassifier.CalculateBinDistance(colorBins, targetColor);

                    // Possible areas where the object we are looking for is are black 0
                    byte newColor = distance >= 125 ? (byte)255 : (byte)0;
                    for (int i = 0; i < width; i++)
                    {
                        for (int j = 0; j < height; j++)
                        {
                            int index = (row + j) * stride + 4 * (column + i);
                            lock ( pixelArrayLock )
                            {
                                colorDistancePixelArray[index] = colorDistancePixelArray[index + 1] = colorDistancePixelArray[index + 2] = newColor;
                            }
                        }
                    }
                });
            });

            // Look at each blob and determine if it is our
            // object with a stricted threshold
            var tempBitmap = new WriteableBitmap(bitmapWidth, bitmapHeight, 96, 96, PixelFormats.Bgr32, null);

            tempBitmap.WritePixels(new Int32Rect(0, 0, bitmapWidth, bitmapHeight), colorDistancePixelArray, stride, 0);

            double minDistance     = double.PositiveInfinity;
            var    allBlobDistance = GetColorBinDistance(pixelArray, colorDistancePixelArray, stride, targetColor, tempBitmap, Colors.Black);

            if (allBlobDistance <= 105)
            {
                minDistance = allBlobDistance;
            }

            var blobColors = BitmapColorer.ColorBitmap(tempBitmap);

            foreach (var color in blobColors)
            {
                var distance = GetColorBinDistance(pixelArray, colorDistancePixelArray, stride, targetColor, tempBitmap, color);
                if (distance <= minDistance)
                {
                    minDistance = distance;
                }
            }
            return(minDistance);
        }
예제 #2
0
        private static double GetColorBinDistance(byte[] pixelArray, byte[] thresholdedPixelArray, int stride, double[] targetHistogram, WriteableBitmap tempBitmap, Color color)
        {
            var boundingBox = BitmapColorer.GetBoundingBoxOfColor(tempBitmap, color);

            var croppedPixelArray       = pixelArray.CropPixelArray((int)boundingBox.X, (int)boundingBox.Y, (int)boundingBox.Width, (int)boundingBox.Height, stride);
            var croppedThresholdedArray = thresholdedPixelArray.CropPixelArray((int)boundingBox.X, (int)boundingBox.Y, (int)boundingBox.Width, (int)boundingBox.Height, stride);
            var colorBins = ColorClassifier.GetColorBinsWithinBlob(croppedPixelArray, croppedThresholdedArray, true);
            var distance  = ColorClassifier.CalculateBinDistance(colorBins, targetHistogram);

            return(distance);
        }