예제 #1
0
        /// <summary>
        /// Computes a sum of the values in the array starting at (<paramref name="row"/>, <paramref name="column"/>) in <paramref name="channel" />
        /// in a rectangle described by the offset and size in <paramref name="rect"/>.
        /// </summary>
        /// <param name="handler">The handler used to perform the operation</param>
        /// <param name="row">Reference row</param>
        /// <param name="column">Reference column</param>
        /// <param name="channel">Channel to draw values from</param>
        /// <param name="rect">Offset and size of the rectangle</param>
        /// <returns>The sum of all values in the rectangle</returns>
        public static T ComputeRectangleSum <T>(this IArrayHandler <T> handler, int row, int column, int channel, Rectangle rect)
        {
            int startRow    = row + rect.Top;
            int startColumn = column + rect.Left;
            int rows        = rect.Height;
            int columns     = rect.Width;

            return(handler.ComputeRectangleSum(startRow, startColumn, rows, columns, channel));
        }
예제 #2
0
파일: Canny.cs 프로젝트: qianc123/visionnet
        /// <summary>
        /// Computes an edge image using the provided image.  The lower threshold and higher threshold
        /// provided are those used for hysteresis, on a scale from 0 to 1.
        /// </summary>
        /// <param name="image">The image to use for edge-seeking</param>
        /// <param name="lowThreshold">The lower threshold for hysteresis, from 0 to 1</param>
        /// <param name="highThreshold">The higher threshold for hysteresis, from 0 to 1</param>
        /// <returns></returns>
        public static BinaryImage Compute(
            GradientImage image,
            float lowThreshold,
            float highThreshold
            )
        {
            IArrayHandler <byte> nms = NonMaximalSuppression(image);

            return(Hysteresis(image, nms, lowThreshold, highThreshold));
        }
예제 #3
0
        /// <summary>
        /// Convolves an image with the provided two-dimensional kernel.  This is done in the spatial
        /// domain, and as such is not as efficient as using an Fast Fourier Transform.
        /// </summary>
        /// <typeparam name="I">Any image whose pixel values are stored as floats</typeparam>
        /// <param name="image">Image to convolve</param>
        /// <param name="kernel">The two-dimensional kernel.</param>
        /// <returns>The filtered image</returns>
        public static unsafe I Convolve <I>(IArrayHandler <float> image, float[,] kernel)
            where I : IArrayHandler <float>, new()
        {
            int rows          = image.Rows;
            int columns       = image.Columns;
            int channels      = image.Channels;
            int krows         = kernel.GetLength(1);
            int kcols         = kernel.GetLength(0);
            int kernelCenterX = kcols / 2;
            int kernelCenterY = krows / 2;
            int stride        = columns * channels;

            float[, ,] data = new float[rows, columns, channels];
            fixed(float *src = image.RawArray, dst = data, knl = kernel)
            {
                float *srcPtr       = src + kernelCenterY * stride + kernelCenterX * channels;
                float *srcScanStart = src;
                float *dstPtr       = dst + kernelCenterY * stride + kernelCenterX * channels;

                for (int r = kernelCenterY; r < rows - kernelCenterY; r++)
                {
                    for (int c = 0; c < columns; c++, srcPtr += channels, srcScanStart += channels)
                    {
                        float[] sums    = new float[channels];
                        float * srcScan = srcScanStart;
                        float * knlPtr  = knl;
                        for (int u = 0; u < krows; u++, srcScan += stride - kcols * channels)
                        {
                            for (int v = 0; v < kcols; v++, knlPtr++)
                            {
                                float mult = *knlPtr;
                                for (int i = 0; i < channels; i++, srcScan++)
                                {
                                    sums[i] += mult * *srcScan;
                                }
                            }
                        }
                        for (int i = 0; i < channels; i++)
                        {
                            *dstPtr++ = sums[i];
                        }
                    }
                }
            }

            I result = new I();

            result.SetData(data);
            return(result);
        }
예제 #4
0
        /// <summary>
        /// Computes an integral image in one pass from the source image.
        /// </summary>
        /// <param name="input">Source image</param>
        /// <returns>Integral image</returns>
        public static unsafe T ComputeInteger <T>(IArrayHandler <int> input) where T : IArrayHandler <int>, new()
        {
            int rows     = input.Rows;
            int columns  = input.Columns;
            int channels = input.Channels;

            int[, ,] ii = new int[rows + 1, columns + 1, channels];
            int[, ,] s  = new int[rows + 1, columns + 1, channels];
            int stride = (columns + 1) * channels;

            fixed(int *iiScan = ii, sScan = s, src = input.RawArray)
            {
                int *srcPtr = src;
                int *iiPtrM = iiScan + stride;
                int *iiPtr  = iiPtrM + channels;
                int *sPtrM  = sScan + channels;
                int *sPtr   = sPtrM + stride;

                for (int r = 1; r < rows + 1; r++)
                {
                    for (int c = 1; c < columns + 1; c++)
                    {
                        for (int i = 0; i < channels; i++)
                        {
                            int val   = *srcPtr++;
                            *   sPtr  = *sPtrM + val;
                            *   iiPtr = *iiPtrM + *sPtr;

                            sPtr++;
                            iiPtr++;
                            sPtrM++;
                            iiPtrM++;
                        }
                    }
                    sPtrM  += channels;
                    sPtr   += channels;
                    iiPtrM += channels;
                    iiPtr  += channels;
                }
            }

            T result = new T();

            result.SetData(ii);
            result.IsIntegral = true;

            return(result);
        }
예제 #5
0
        /// <summary>
        /// Fills a handler with the provided value.
        /// </summary>
        /// <typeparam name="T">The underlying type of the handler</typeparam>
        /// <param name="handler">The handler to fill</param>
        /// <param name="value">The value to fill with</param>
        public static void Fill <T>(this IArrayHandler <T> handler, T value)
        {
            T[, ,] data = handler.RawArray;
            int rows     = handler.Rows;
            int columns  = handler.Columns;
            int channels = handler.Channels;

            for (int r = 0; r < rows; r++)
            {
                for (int c = 0; c < columns; c++)
                {
                    for (int i = 0; i < channels; i++)
                    {
                        data[r, c, i] = value;
                    }
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Interpolates the value in-between cells in an array using bi-linear interpolation.
        /// </summary>
        /// <param name="handler">The array to use</param>
        /// <param name="row">The real-valued row</param>
        /// <param name="column">The real-valued column</param>
        /// <param name="channel">The image channel</param>
        /// <returns>An interpolated value</returns>
        public static float InterploateLinear(this IArrayHandler <float> handler, float row, float column, int channel)
        {
            row    = row < 0 ? 0 : row;
            column = column < 0 ? 0 : column;
            int i0 = (int)row;
            int j0 = (int)column;
            int i1 = i0 + 1;

            i1 = i1 < handler.Rows ? i1 : handler.Rows - 1;
            int j1 = j0 + 1;

            j1 = j1 < handler.Columns ? j1 : handler.Columns - 1;

            float di = row - i0;
            float dj = column - j0;

            return(handler[i0, j0, channel] * (1 - di) * (1 - dj) +
                   handler[i0, j1, channel] * (1 - di) * dj +
                   handler[i1, j0, channel] * di * (1 - dj) +
                   handler[i1, j1, channel] * di * dj);
        }
예제 #7
0
            public float Compute(ImageDataPoint <float> point)
            {
                if (point.ImageID != _currentID)
                {
                    _currentID = point.ImageID;
                    if (point.Image.IsIntegral || DecisionTree <ImageDataPoint <float>, float[]> .IsBuilding)
                    {
                        _integralImage = point.Image;
                    }
                    else
                    {
                        _integralImage = IntegralImage.ComputeFloat <FloatArrayHandler>(point.Image);
                    }
                }
                int   row    = point.Row;
                int   column = point.Column;
                float sum    = _integralImage.ComputeRectangleSum(row, column, _channel, _rect);

                Debug.Assert(!float.IsNaN(sum), "Rectangle sum is NaN");
                return(sum);
            }
예제 #8
0
        /// <summary>
        /// Extracts a channel as a Grayscale image.  Uses the <see cref="M:IArrayHandler.ExtractChannel"/> method.
        /// </summary>
        /// <param name="handler">The image upon which to operate</param>
        /// <param name="channel">The channel to extract</param>
        /// <returns>An image representation of the channel</returns>
        public static unsafe GrayscaleImage ExtractChannelAsImage(this IArrayHandler <float> handler, int channel)
        {
            float[,] buffer = handler.ExtractChannel(channel);
            int rows    = handler.Rows;
            int columns = handler.Columns;

            float[, ,] data = new float[rows, columns, 1];
            fixed(float *channelSrc = buffer, dataSrc = data)
            {
                float *channelPtr = channelSrc;
                float *dataPtr    = dataSrc;
                int    count      = rows * columns;

                while (count-- > 0)
                {
                    *dataPtr++ = *channelPtr++;
                }
            }

            GrayscaleImage gray = new GrayscaleImage();

            gray.SetData(data);
            return(gray);
        }
예제 #9
0
 /// <summary>
 /// Convolves an image with the provided kernel.  The kernel is assumed to be radially invariant, seperable and
 /// take  the form {center value, value 1 pixel from center, value 2 pixels from center, etc.}.
 /// </summary>
 /// <typeparam name="I">Any image whose pixel values are stored as floats</typeparam>
 /// <param name="image">The image to convolve.</param>
 /// <param name="kernel">The kernel to use for convolution</param>
 /// <returns>A fitlered image</returns>
 public static I ConvolveHalf <I>(IArrayHandler <float> image, float[] kernel) where I : IArrayHandler <float>, new()
 {
     return(ConvolveHalf <I>(image, kernel, 1));
 }
예제 #10
0
파일: Canny.cs 프로젝트: qianc123/visionnet
        private static unsafe BinaryImage Hysteresis(GradientImage grad, IArrayHandler <byte> nms, float tlow, float thigh)
        {
            int r, c, pos, numedges, highcount;

            int[] hist = new int[short.MaxValue];
            float maximum_mag, lowthreshold, highthreshold;

            maximum_mag         = 0;
            float[,] magChannel = grad.ExtractChannel(0);
            short[] mag = new short[magChannel.Length];
            fixed(short *dst = mag)
            {
                fixed(float *src = magChannel)
                {
                    float *srcPtr = src;
                    short *dstPtr = dst;

                    for (int i = 0; i < mag.Length; i++, srcPtr++, dstPtr++)
                    {
                        *dstPtr = (short)(*srcPtr * 255);
                    }
                }
            }

            int rows = grad.Rows;
            int cols = grad.Columns;

            byte[] edge = new byte[rows * cols];
            fixed(byte *src = nms.RawArray)
            {
                byte *srcPtr = src;
                int   length = rows * cols;

                for (pos = 0; pos < length; pos++)
                {
                    if (*srcPtr++ == POSSIBLE_EDGE)
                    {
                        edge[pos] = POSSIBLE_EDGE;
                    }
                    else
                    {
                        edge[pos] = NOEDGE;
                    }
                }
            }

            for (r = 0, pos = 0; r < rows; r++, pos += cols)
            {
                edge[pos]            = NOEDGE;
                edge[pos + cols - 1] = NOEDGE;
            }
            pos = (rows - 1) * cols;
            for (c = 0; c < cols; c++, pos++)
            {
                edge[c]   = NOEDGE;
                edge[pos] = NOEDGE;
            }

            for (r = 0; r < short.MaxValue; r++)
            {
                hist[r] = 0;
            }
            for (r = 0, pos = 0; r < rows; r++)
            {
                for (c = 0; c < cols; c++, pos++)
                {
                    if (edge[pos] == POSSIBLE_EDGE)
                    {
                        hist[mag[pos]]++;
                    }
                }
            }

            for (r = 1, numedges = 0; r < short.MaxValue; r++)
            {
                if (hist[r] != 0)
                {
                    maximum_mag = (short)r;
                }
                numedges += hist[r];
            }

            highcount = (int)(numedges * thigh + 0.5);

            r        = 1;
            numedges = hist[1];
            while ((r < (maximum_mag - 1)) && (numedges < highcount))
            {
                r++;
                numedges += hist[r];
            }
            highthreshold = (short)r;
            lowthreshold  = (short)(highthreshold * tlow + 0.5);

            for (r = 0, pos = 0; r < rows; r++)
            {
                for (c = 0; c < cols; c++, pos++)
                {
                    if ((edge[pos] == POSSIBLE_EDGE) && (mag[pos] >= highthreshold))
                    {
                        edge[pos] = EDGE;
                        follow_edges(edge, mag, pos, lowthreshold, cols);
                    }
                }
            }

            for (r = 0, pos = 0; r < rows; r++)
            {
                for (c = 0; c < cols; c++, pos++)
                {
                    if (edge[pos] != EDGE)
                    {
                        edge[pos] = NOEDGE;
                    }
                }
            }
            BinaryImage edgeImage = new BinaryImage(rows, cols);

            fixed(bool *dst = edgeImage.RawArray)
            {
                bool *dstPtr = dst;
                int   length = rows * cols;

                for (pos = 0; pos < length; pos++)
                {
                    *dstPtr++ = edge[pos] == EDGE;
                }
            }

            return(edgeImage);
        }
예제 #11
0
 /// <summary>
 /// Extracts a rectangle from a handler.
 /// </summary>
 /// <typeparam name="T">Underlying type of the handler</typeparam>
 /// <param name="handler">The handler used in extraction</param>
 /// <param name="rect">The rectangle to extract</param>
 /// <returns>The extracted rectangle</returns>
 public static T[, ,] ExtractRectangle <T>(this IArrayHandler <T> handler, Rectangle rect)
 {
     return(handler.ExtractRectangle(rect.R, rect.C, rect.Rows, rect.Columns));
 }
예제 #12
0
 /// <summary>
 /// Convolves an image with the provided kernels.  These Kernels are full kernels, in that they go from
 /// a minimum value to a maximum value.  There are no restrictions on what these kernels can be, though
 /// the user is cautioned to make sure that they are passing kernels which make sense, as this code
 /// does not check for any of the necessary kernel conditions.
 /// </summary>
 /// <typeparam name="I">Any image whose pixel values are stored as floats</typeparam>
 /// <param name="image">The image to convolve.</param>
 /// <param name="kernel">The kernel to use for convolution in the horizontal direction</param>
 /// <param name="subsample">The subsampling frequency</param>
 /// <returns>a fitlered image</returns>
 public static I ConvolveFull <I>(IArrayHandler <float> image, float[] kernel, int subsample)
     where I : IArrayHandler <float>, new()
 {
     return(ConvolveFull <I>(image, kernel, kernel, subsample));
 }
예제 #13
0
        /// <summary>
        /// Computes an integral image in one pass from the source image.
        /// </summary>
        /// <param name="input">Source image</param>
        /// <returns>Integral image</returns>
        public static unsafe T ComputeFloat <T>(IArrayHandler <float> input) where T : IArrayHandler <float>, new()
        {
            int rows     = input.Rows;
            int columns  = input.Columns;
            int channels = input.Channels;

            float[, ,] ii = new float[rows + 1, columns + 1, channels];
            float[, ,] s  = new float[rows + 1, columns + 1, channels];
            //float[, ,] s2 = computeStandardDeviation ? new float[rows + 1, columns + 1, channels] : null;
            //float[, ,] ii2 = computeStandardDeviation ? new float[rows + 1, columns + 1, channels] : null;
            int stride = (columns + 1) * channels;

            fixed(float *iiScan = ii, sScan = s, /*s2Scan = s2, ii2Scan = ii2,*/ src = input.RawArray)
            {
                float *srcPtr = src;
                float *iiPtrM = iiScan + stride;
                float *iiPtr  = iiPtrM + channels;
                float *sPtrM  = sScan + channels;
                float *sPtr   = sPtrM + stride;

                //float* ii2PtrM = computeStandardDeviation ? ii2Scan + stride : null;
                //float* ii2Ptr = computeStandardDeviation ? ii2PtrM + channels : null;
                //float* s2PtrM = computeStandardDeviation ? s2Scan + channels : null;
                //float* s2Ptr = computeStandardDeviation ? s2PtrM + stride : null;

                for (int r = 1; r < rows + 1; r++)
                {
                    for (int c = 1; c < columns + 1; c++)
                    {
                        for (int i = 0; i < channels; i++)
                        {
                            //float assert = 0;
                            //for (int rr = 0; rr < r; rr++)
                            //    for (int cc = 0; cc < c; cc++)
                            //        assert += input[rr, cc, i];
                            float val = *srcPtr++;
                            //float val = input[r-1, c-1, i];
                            // normal
                            *sPtr = *sPtrM + val;
                            //s[r, c, i] = s[r - 1, c, i] + val;
                            *iiPtr = *iiPtrM + *sPtr;
                            //ii[r, c, i] = ii[r, c - 1, i] + s[r, c, i];
                            // squared
                            //if (computeStandardDeviation)
                            //{
                            //    *s2Ptr = *s2PtrM + val * val;
                            //    //s2[r, c, i] = s2[r - 1, c, i] + val * val;
                            //    *ii2Ptr = *ii2PtrM + *s2Ptr;
                            //    //ii2[r, c, i] = ii2[r, c - 1, i] + s2[r, c, i];
                            //}

                            sPtr++;
                            iiPtr++;
                            sPtrM++;
                            iiPtrM++;
                            //if (computeStandardDeviation)
                            //{
                            //    ii2PtrM++;
                            //    s2Ptr++;
                            //    ii2Ptr++;
                            //    s2PtrM++;
                            //}

                            //if (assert != ii[r, c, i])
                            //    Console.WriteLine("hmmm");
                        }
                    }
                    sPtrM  += channels;
                    sPtr   += channels;
                    iiPtrM += channels;
                    iiPtr  += channels;
                    //if (computeStandardDeviation)
                    //{
                    //    s2PtrM += channels;
                    //    s2Ptr += channels;
                    //    ii2PtrM += channels;
                    //    ii2Ptr += channels;
                    //}
                }
            }

            //float[] stddev = new float[channels];
            //if (computeStandardDeviation)
            //{
            //    for (int i = 0; i < channels; i++)
            //    {
            //        float sum = ii[rows, columns, i];
            //        float squaredSum = ii2[rows, columns, i];
            //        int count = rows * columns;
            //        float mean = sum / count;
            //        float variance = squaredSum / count - mean * mean;
            //        stddev[i] = (float)Math.Sqrt(variance);
            //    }
            //}
            s = null;
            GC.Collect();

            T result = new T();

            result.SetData(ii);
            result.IsIntegral = true;

            return(result);
        }
예제 #14
0
        /// <summary>
        /// Convolves an image with the provided kernels.  These Kernels are full kernels, in that they go from
        /// a minimum value to a maximum value.  There are no restrictions on what these kernels can be, though
        /// the user is cautioned to make sure that they are passing kernels which make sense, as this code
        /// does not check for any of the necessary kernel conditions.
        /// </summary>
        /// <typeparam name="I">Any image whose pixel values are stored as floats</typeparam>
        /// <param name="image">The image to convolve.</param>
        /// <param name="kernelx">The kernel to use for convolution in the horizontal direction</param>
        /// <param name="kernely">The kernel to use for convolution in the vertical direction</param>
        /// <param name="subsample">The subsampling frequency</param>
        /// <returns>a fitlered image</returns>
        public static unsafe I ConvolveFull <I>(IArrayHandler <float> image, float[] kernelx, float[] kernely, int subsample)
            where I : IArrayHandler <float>, new()
        {
            int rows     = image.Rows;
            int columns  = image.Columns;
            int channels = image.Channels;
            int sizex    = kernelx.Length;
            int halfx    = sizex / 2;
            int sizey    = kernely.Length;
            int halfy    = sizey / 2;

            float[, ,] dest = new float[rows, columns, channels];
            fixed(float *src = image.RawArray, dst = dest, knl = kernely)
            {
                float *srcPtr = src;
                float *dstPtr = dst;
                int    stride = columns * channels;

                for (int r = 0; r < rows; r++)
                {
                    for (int c = 0; c < columns; c++)
                    {
                        for (int i = 0; i < channels; i++, srcPtr++)
                        {
                            float *knlPtr = knl;
                            int    diff   = -halfy;
                            if (r + diff < 0)
                            {
                                diff = -r;
                            }
                            float *srcScan = srcPtr + diff * stride;
                            float  sum     = 0;
                            for (int k = 0, rr = r - halfy; k < sizey; k++, knlPtr++, rr++)
                            {
                                sum += *knlPtr * *srcScan;
                                if (rr >= 0 && rr < rows - 1)
                                {
                                    srcScan += stride;
                                }
                            }
                            *dstPtr++ = sum;
                        }
                    }
                }
            }

            int nrows    = rows / subsample;
            int ncolumns = columns / subsample;

            float[, ,] source = dest;
            dest = new float[nrows, ncolumns, channels];
            fixed(float *src = source, dst = dest, knl = kernelx)
            {
                float *srcPtr = src;
                float *dstPtr = dst;
                int    stride = columns * channels;

                for (int r = 0, tr = 0; r < nrows; r++, tr += subsample, srcPtr += subsample * stride)
                {
                    float *srcScan = srcPtr;
                    for (int c = 0, tc = 0; c < ncolumns; c++, tc += subsample, srcScan += channels * (subsample - 1))
                    {
                        for (int i = 0; i < channels; i++, srcScan++)
                        {
                            float *knlPtr = knl;
                            int    diff   = -halfx;
                            if (tc + diff < 0)
                            {
                                diff = -tc;
                            }
                            float *srcScan1 = srcScan + diff * channels;
                            float  sum      = 0;
                            for (int k = 0, cc = tc - halfx; k < sizex; k++, knlPtr++, cc++)
                            {
                                sum += *knlPtr * *srcScan1;
                                if (cc >= 0 && cc < columns - 1)
                                {
                                    srcScan1 += channels;
                                }
                            }
                            *dstPtr++ = sum;
                        }
                    }
                }
            }

            I result = new I();

            result.SetData(dest);
            return(result);
        }
예제 #15
0
        /// <summary>
        /// Convolves an image with the provided kernels.  Both kernels are assumed to be radially invariant, seperable and
        /// take the form {center value, value 1 pixel from center, value 2 pixels from center, etc.}.  The result is
        /// sub-sampled using the provided frequency.
        /// </summary>
        /// <typeparam name="I">Any image whose pixel values are stored as floats</typeparam>
        /// <param name="image">The image to convolve.</param>
        /// <param name="kernelx">The kernel to use for convolution in the horizontal direction</param>
        /// <param name="kernely">The kernel to use for convolution in the vertical direction</param>
        /// <param name="subsample">The subsampling frequency</param>
        /// <returns>a fitlered image</returns>
        public static unsafe I ConvolveHalf <I>(IArrayHandler <float> image, float[] kernelx, float[] kernely, int subsample)
            where I : IArrayHandler <float>, new()
        {
            int rows     = image.Rows;
            int columns  = image.Columns;
            int channels = image.Channels;
            int sizex    = kernelx.Length;
            int sizey    = kernely.Length;

            float[, ,] dest = new float[rows, columns, channels];
            fixed(float *src = image.RawArray, dst = dest, knl = kernely)
            {
                float *srcPtr = src;
                float *dstPtr = dst;
                int    stride = columns * channels;

                for (int r = 0; r < rows; r++)
                {
                    for (int c = 0; c < columns; c++)
                    {
                        for (int i = 0; i < channels; i++, srcPtr++, dstPtr++)
                        {
                            float *knlPtr = knl;
                            float  sum    = *knlPtr * *srcPtr;
                            knlPtr++;
                            for (int k = 1; k < sizey; k++, knlPtr++)
                            {
                                int diff = k * stride;
                                int nr   = r - k;
                                int pr   = r + k;
                                if (nr < 0)
                                {
                                    sum += 2 * (*knlPtr * *(srcPtr + diff));
                                }
                                else if (pr >= rows)
                                {
                                    sum += 2 * (*knlPtr * *(srcPtr - diff));
                                }
                                else
                                {
                                    sum += *knlPtr * *(srcPtr - diff) + *knlPtr * *(srcPtr + diff);
                                }
                            }
                            *dstPtr = sum;
                        }
                    }
                }
            }

            int nrows    = rows / subsample;
            int ncolumns = columns / subsample;

            float[,,] source = dest;
            dest             = new float[nrows, ncolumns, channels];
            fixed(float *src = source, dst = dest, knl = kernelx)
            {
                int    stride = columns * channels;
                float *srcPtr = src + stride * (subsample / 2) + channels * (subsample / 2);
                float *dstPtr = dst;

                for (int r = 0; r < nrows; r++, srcPtr += subsample * stride)
                {
                    float *srcScan = srcPtr;
                    for (int c = 0; c < ncolumns; c++, srcScan += channels * (subsample - 1))
                    {
                        for (int i = 0; i < channels; i++, srcScan++, dstPtr++)
                        {
                            float *knlPtr = knl;
                            float  sum    = *knlPtr * *srcScan;
                            knlPtr++;
                            for (int k = 1; k < sizex; k++, knlPtr++)
                            {
                                int nc   = c - k;
                                int pc   = c + k;
                                int diff = k * channels;
                                if (nc < 0)
                                {
                                    sum += 2 * (*knlPtr * *(srcScan + diff));
                                }
                                else if (pc >= columns)
                                {
                                    sum += 2 * (*knlPtr * *(srcScan - diff));
                                }
                                else
                                {
                                    sum += *knlPtr * *(srcScan + diff) + *knlPtr * *(srcScan - diff);
                                }
                            }
                            *dstPtr = sum;
                        }
                    }
                }
            }

            I result = new I();

            result.SetData(dest);
            return(result);
        }
예제 #16
0
 /// <summary>
 /// Convolves the provided image with a two dimensional Gaussian of the provided sigma and returns the result.
 /// </summary>
 /// <typeparam name="I">Any image whose pixel values are stored as floats</typeparam>
 /// <param name="image">The image to convolve.</param>
 /// <param name="sigma">The sigma to use in the Gaussian</param>
 /// <returns>A blurred image</returns>
 public static I ConvolveGaussian <I>(IArrayHandler <float> image, float sigma) where I : IArrayHandler <float>, new()
 {
     return(ConvolveGaussian <I>(image, sigma, 1));
 }
예제 #17
0
        /// <summary>
        /// Convolves the provided image with a two dimensional Gaussian of the provided sigma and returns the result,
        /// subsampled as directed.
        /// </summary>
        /// <typeparam name="I">Any image whose pixel values are stored as floats</typeparam>
        /// <param name="image">The image to convolve.</param>
        /// <param name="sigma">The sigma to use in the Gaussian</param>
        /// <param name="subsample">The subsampling frequency.</param>
        /// <returns>A blurred image</returns>
        public static I ConvolveGaussian <I>(IArrayHandler <float> image, float sigma, int subsample) where I : IArrayHandler <float>, new()
        {
            I result = ConvolveHalf <I>(image, Gaussian.ComputeHalfKernel(sigma), subsample);

            return(result);
        }