/// <summary>
        /// Convert an float image to a squared integral image
        /// </summary>
        /// <remarks>
        /// We skip the last line to keep the original size (better performance)
        /// </remarks>
        /// <param name="source">image source</param>
        /// <param name="dest">image destination</param>
        public void IntegralSquare(IImage2DByteA source, IImage2DUIntA dest)
        {
            if (source == null) throw new ArgumentNullException("source");
            if (dest == null) throw new ArgumentNullException("dest");
            if ((source.Width > dest.Width) || (source.Height > dest.Height)) throw new ArgumentException("Destination image (" + dest.Width + "x" + dest.Height + ") must have at least the source image width and height but is only " + source.Width + "x" + source.Height);

            int height = source.Height;
            int width = source.Width;
            byte[] sBuf = source.HostBuffer;
            uint[] dBuf = dest.HostBuffer;

            for (int x = 0; x < width; x++) dest.HostBuffer[x] = 0; // zero first line
            for (int y = 0, a = width * height; y < a; y += width) dest.HostBuffer[y] = 0; // zero first column

            // for each line
            int ySumIndex = 0;
            int y1SumIndex;
            int yIndex = 0;
            for (int y = 1; y < height; y++)
            {
                y1SumIndex = ySumIndex;
                ySumIndex += width;

                // for each pixel
                for (int x = 1; x < width; x++)
                {
                    uint p = sBuf[yIndex + x - 1];
                    dBuf[ySumIndex + x] = p * p + dBuf[ySumIndex + x - 1] + dBuf[y1SumIndex + x] - dBuf[y1SumIndex + x - 1];
                }
                yIndex += width;
            }
        }
        /// <summary>
        /// Convert an float image to an integral image
        /// </summary>
        /// <remarks>
        /// We skip the last line to keep the original size (better performance)
        /// </remarks>
        /// <param name="source">image source</param>
        /// <param name="dest">image destination</param>
        public void Integral(IImage2DByteA source, IImage2DUIntA dest)
        {
            if (source == null) throw new ArgumentNullException("source");
            if (dest == null) throw new ArgumentNullException("dest");
            if ((source.Width > dest.Width) || (source.Height > dest.Height)) throw new ArgumentException("Destination image (" + dest.Width + "x" + dest.Height + ") must have at least the source image width and height but is only " + source.Width + "x" + source.Height);

            int heightS = source.Height;
            int widthS = source.Width;
            int heightD = dest.Height;
            int widthD = dest.Width;
            byte[] sBuf = source.HostBuffer;
            uint[] dBuf = dest.HostBuffer;

            for (int x = 0; x < widthD; x++) dest.HostBuffer[x] = 0; // zero first line
            for (int y = 0, a = widthD * heightD; y < a; y += widthD) dest.HostBuffer[y] = 0; // zero first column

            int y1IndexS = 0;
            int yIndexD = widthD;
            int y1IndexD = 0; // last

            // for each line
            for (int y = 1; y < heightS; y++)
            {
                // for each pixel
                for (int x = 1; x < widthS; x++)
                {
                    uint p = sBuf[y1IndexS + x - 1];
                    dBuf[yIndexD + x] = p + dBuf[yIndexD + x - 1] + dBuf[y1IndexD + x] - dBuf[y1IndexD + x - 1];
                }

                yIndexD += widthD;
                y1IndexS += widthS;
                y1IndexD += widthD;
            }
        }
 /// <summary>
 /// Free resources being used
 /// </summary>
 public void Dispose()
 {
     try { if (_ownIntegralImage) { _integralImage.Dispose(); _integralImage = null; } }
     catch { }
     try { if (_ownIntegral2Image) { _integral2Image.Dispose(); _integral2Image = null; } }
     catch { }
     try { if (_ownResultRectangles) { _resultRectangles.Dispose(); _resultRectangles = null; } }
     catch { }
 }
        /// <summary>
        /// Detects the presence of an object in a given window.
        /// </summary>
        protected bool Compute(HaarFeatureNode[] stageNodes,
            int stagesCount,
            int[] stageNodeCounts, float[] stageThresholds,
            IImage2DUIntA integralImage,
            IImage2DUIntA integral2Image,
            float invArea,
            int x, int y, int w, int h)
        {
            float mean = (float)integralImage.GetIntegralSum(x, y, w, h) * invArea;
            float normFactor = (float)integral2Image.GetIntegralSum(x, y, w, h) * invArea
                - (mean * mean);

            normFactor = (normFactor >= 0) ? (float)Math.Sqrt(normFactor) : 1;

            int pos = 0;
            for (int j = 0; j < stagesCount; j++)
            {
                int count = stageNodeCounts[j];
                float threshold = stageThresholds[j];

                float value = 0;
                for (int i = 0; i < count; i++)
                {
                    // evaluate the node's feature
                    float sum = HaarExtensions.GetNodeSum(ref stageNodes[pos], integralImage, x, y);

                    // and increase the value accumulator
                    HaarFeatureNode node = stageNodes[pos++];
                    value += ((sum < node.Threshold * normFactor) ? node.LeftValue : node.RightValue);
                }

                if (value <= threshold) return false; // window has been rejected
            }
            return true;
        }
Beispiel #5
0
 /// <summary>
 /// Gets the sum of a rectangular feature in an integral image.
 /// </summary>
 public static float GetSum(ref HaarRectangle rect, IImage2DUIntA integralImage, int x, int y)
 {
     return integralImage.GetIntegralSum(x + rect.ScaledX, y + rect.ScaledY, rect.ScaledWidth, rect.ScaledHeight) * rect.ScaledWeight;
 }
Beispiel #6
0
        /// <summary>
        /// Gets the sum of the areas of the rectangular features in an integral image.
        /// </summary>
        public static float GetNodeSum(ref HaarFeatureNode node, IImage2DUIntA integralImage, int x, int y)
        {
            float sum;
            sum = GetSum(ref node.Rect1, integralImage, x, y);
            sum += GetSum(ref node.Rect2, integralImage, x, y);
            if (node.RectCount == 3) sum += GetSum(ref node.Rect3, integralImage, x, y);

            return sum;
        }