Пример #1
0
        public GrayImage Filter1DSymmetric(GrayImage data, float[] filter, bool transpose)
        {
            GrayImage image = transpose ? new GrayImage(data.Height, data.Width) : new GrayImage(data.Width, data.Height);
            int       num   = 0;
            int       num2  = transpose ? num : (num * image.Width);
            FilterJob job2  = new FilterJob();

            job2.filter  = filter;
            job2.data    = data;
            job2.destPtr = num2;
            job2.result  = image;
            job2.start   = num;
            job2.end     = data.Height / 2;
            FilterJob parameter            = job2;
            ParameterizedThreadStart start = transpose ? new ParameterizedThreadStart(this.FilterPartSymmetricT) : new ParameterizedThreadStart(this.FilterPartSymmetric);
            Thread thread = new Thread(start);

            thread.Start(parameter);
            num               = data.Height / 2;
            num2              = transpose ? num : (num * image.Width);
            parameter.start   = num;
            parameter.destPtr = num2;
            parameter.end     = data.Height;
            start(parameter);
            thread.Join();
            return(image);
        }
Пример #2
0
        /// <summary>
        /// Convolves an GrayImage with a 2D-symmetric operator.
        /// </summary>
        /// <param name="data">Data to be convolved with the operator</param>
        /// <param name="opUL">Lower-right quadrant of the operator.</param>
        /// <returns></returns>
        private GrayImage Conv2DSymm(GrayImage data, GrayImage opLR)
        {
            if (opLR.Width % 2 != 0 || opLR.Height % 2 != 0)
            {
                throw new ArgumentException("Operator must have an even number of rows and columns.");
            }

            int xPad = opLR.Width - 1;
            int yPad = opLR.Height - 1;

            GrayImage result = new GrayImage(data.Width - 2 * xPad, data.Height - 2 * yPad);

            for (int y = yPad; y < data.Height - yPad; y++)
            {
                for (int x = xPad; x < data.Width - xPad; x++)
                {
                    // Center pixel
                    float pixel = data[x, y] * opLR.Scan0[0];

                    // Vertical center
                    for (int op_y = 1; op_y < opLR.Height; op_y++)
                    {
                        pixel += (data[x, y + op_y] + data[x, y - op_y]) * opLR[0, op_y];
                    }

                    //Horizontal center
                    for (int op_x = 1; op_x < opLR.Width; op_x++)
                    {
                        pixel += (data[x + op_x, y] + data[x - op_x, y]) * opLR[op_x, 0];
                    }

                    //Quadrants
                    int opIdx = 1;

                    for (int op_y = 1; op_y < opLR.Height; op_y++)
                    {
                        int baseIdx1 = ((y + op_y) * data.Width) + x;
                        int baseIdx2 = ((y - op_y) * data.Width) + x;

                        // Loop unrolling can save 25% execution time here

                        for (int op_x = 1; op_x < opLR.Width; op_x++)
                        {
                            pixel += (data.Scan0[baseIdx1 + op_x] +
                                      data.Scan0[baseIdx2 + op_x] +
                                      data.Scan0[baseIdx1 - op_x] +
                                      data.Scan0[baseIdx2 - op_x]) * opLR.Scan0[opIdx];

                            opIdx++;
                        }

                        opIdx++; // Skip 0th col on next row
                    }

                    result[x - xPad, y - yPad] = pixel;
                } // loop over data x
            }     // loop over data y

            return(result);
        }
Пример #3
0
        public GrayImage Conv2DSeparable(GrayImage data, float[] filter)
        {
            GrayImage pass1 = Filter1DSymmetric(data, filter, true);
            GrayImage result = Filter1DSymmetric(pass1, filter, true);

            return result;
        }
        protected override void ApplyFilter()
        {
            // get source image size
            int width  = _sourceData[0].GetLength(0),
                height = _sourceData[0].GetLength(1);

            int channels = _sourceData.Length;

            // Estimate a good filter size for the gaussian.
            // Note that gaussian isn't an ideal bandpass filter
            //  so this is an experimentally determined quantity
            double std = (width / _newWidth) * 0.50;

            for (int i = 0; i < channels; i++)
            {
                GrayImage channel = new GrayImage(_sourceData[i]);

                channel = Convolution.Instance.GaussianConv(channel, std);

                _sourceData[i] = channel.ToByteArray2D();
            }

            // number of pixels to shift in the original image
            double xStep = (double)width / _newWidth,
                   yStep = (double)height / _newHeight;


            NNResize resizer = new NNResize();

            _destinationData = resizer.Apply(_sourceData, _newWidth, _newHeight);
        }
Пример #5
0
        /// <summary>
        /// Filters an GrayImage with a 1D symmetric filter along the X-axis.
        /// (This operation is multithreaded)
        /// </summary>
        /// <param name="data">GrayImage to be operated on</param>
        /// <param name="filter">Filter to use (center tap plus right-hand-side)</param>
        /// <param name="transpose">Transpose the result?</param>
        /// <returns>Transposed, filtered GrayImage.</returns>
        public GrayImage Filter1DSymmetric(GrayImage data, float[] filter, bool transpose)
        {
            GrayImage result = transpose ?
                new GrayImage(data.Height, data.Width) :
                new GrayImage(data.Width, data.Height);

#if SILVERLIGHT || WIN
            int startY = 0;

            int destPtr = transpose ?  startY : (startY * result.Width);

            FilterJob job
                = new FilterJob
                {
                    filter = filter,
                    data = data,
                    destPtr = destPtr,
                    result = result,
                    start = startY,
                    end = data.Height / 2
                };

            ParameterizedThreadStart del = transpose ?
                new ParameterizedThreadStart(FilterPartSymmetricT) :
                new ParameterizedThreadStart(FilterPartSymmetric);

            Thread worker = new Thread(del);
            worker.Start(job);

            startY = data.Height / 2;
            destPtr = transpose ?  startY : (startY * result.Width);


            job.start = startY;
            job.destPtr = destPtr;
            job.end = data.Height;

            del((object)job); // Run the appropriate filter in this thread, too

            worker.Join();
#else
            FilterJob job
                = new FilterJob
                {
                    filter = filter,
                    data = data,
                    destPtr = 0,
                    result = result,
                    start = 0,
                    end = data.Height
                };

            if (transpose)
                FilterPartSymmetricT(job);
            else
                FilterPartSymmetric(job);
#endif

            return result;
        }
        protected override void ApplyFilter()
        {
            // get source image size
            int width = _sourceData[0].GetLength(0),
                height = _sourceData[0].GetLength(1);

            int channels = _sourceData.Length;

            // Estimate a good filter size for the gaussian.
            // Note that gaussian isn't an ideal bandpass filter
            //  so this is an experimentally determined quantity
            double std = (width / _newWidth) * 0.50;

            for(int i = 0; i < channels; i++)
            {
                GrayImage channel = new GrayImage(_sourceData[i]);

                channel = Convolution.Instance.GaussianConv(channel, std);

                _sourceData[i] = channel.ToByteArray2D();
            }

            // number of pixels to shift in the original image
            double xStep = (double)width / _newWidth,
                   yStep = (double)height / _newHeight;


            NNResize resizer = new NNResize();

             _destinationData = resizer.Apply(_sourceData, _newWidth, _newHeight);


        }
Пример #7
0
        public GrayImage Conv2DSeparable(GrayImage data, float[] filter)
        {
            GrayImage pass1  = Filter1DSymmetric(data, filter, true);
            GrayImage result = Filter1DSymmetric(pass1, filter, true);

            return(result);
        }
Пример #8
0
        public void FilterPartSymmetric(object filterJob)
        {
            FilterJob filterJob2 = (FilterJob)filterJob;
            GrayImage data       = filterJob2.data;

            float[] scan    = data.Scan0;
            float[] filter  = filterJob2.filter;
            float[] scan2   = filterJob2.result.Scan0;
            int     num     = filter.Length - 1;
            int     destPtr = filterJob2.destPtr;

            for (int i = filterJob2.start; i < filterJob2.end; i++)
            {
                int num2 = i * data.Width;
                for (int j = 0; j < num; j++)
                {
                    float num3 = scan[num2] * filter[0];
                    for (int k = 1; k < j + 1; k++)
                    {
                        num3 += (scan[num2 + k] + scan[num2 - k]) * filter[k];
                    }
                    for (int l = j + 1; l < filter.Length; l++)
                    {
                        num3 += (scan[num2 + l] + scan[num2 + l]) * filter[l];
                    }
                    scan2[destPtr++] = num3;
                    num2++;
                }
                for (int m = num; m < data.Width - num; m++)
                {
                    float num4 = scan[num2] * filter[0];
                    for (int n = 1; n < filter.Length; n++)
                    {
                        num4 += (scan[num2 + n] + scan[num2 - n]) * filter[n];
                    }
                    scan2[destPtr++] = num4;
                    num2++;
                }
                for (int num5 = data.Width - num; num5 < data.Width; num5++)
                {
                    float num6 = scan[num2] * filter[0];
                    for (int num7 = 0; num7 < data.Width - num5; num7++)
                    {
                        num6 += (scan[num2 + num7] + scan[num2 - num7]) * filter[num7];
                    }
                    for (int num8 = data.Width - num5; num8 < filter.Length; num8++)
                    {
                        num6 += (scan[num2 + num8] + scan[num2 - num8]) * filter[num8];
                    }
                    scan2[destPtr++] = num6;
                    num2++;
                }
            }
        }
Пример #9
0
        /// <summary>
        /// Vanilla 2D convolution.  Not optimized.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="op"></param>
        /// <returns></returns>
        public GrayImage Conv2D(GrayImage data, GrayImage op)
        {
            GrayImage result = new GrayImage(data.Width, data.Height);

            if (op.Width % 2 == 0 || op.Height % 2 == 0)
            {
                throw new ArgumentException("Operator must have an odd number of rows and columns.");
            }

            int x_offset = op.Width / 2;
            int y_offset = op.Height / 2;

            for (int y = 0; y < data.Height; y++)
            {
                for (int x = 0; x < data.Width; x++)
                {
                    float pixel = 0;
                    float wt    = 0;

                    for (int op_y = 0; op_y < op.Height; op_y++)
                    {
                        int d_y = y - y_offset + op_y;
                        if (d_y < 0 || d_y >= data.Height)
                        {
                            continue;
                        }

                        for (int op_x = 0; op_x < op.Width; op_x++)
                        {
                            int d_x = x - x_offset + op_x;
                            if (d_x < 0 || d_x >= data.Width)
                            {
                                continue;
                            }

                            float op_val = op[op_x, op_y];

                            /* Perform actual convolution */
                            wt    += Math.Abs(op_val);
                            pixel += data[d_x, d_y] * op_val;
                        }
                    }

                    result[x, y] = pixel / wt;
                } // loop over data x
            }     // loop over data y

            return(result);
        }
Пример #10
0
 protected override void ApplyFilter()
 {
     int length = base._sourceData[0].GetLength(0);
     int num2 = base._sourceData[0].GetLength(1);
     int num3 = base._sourceData.Length;
     double std = (length / base._newWidth) * 0.5;
     for (int i = 0; i < num3; i++)
     {
         GrayImage data = new GrayImage(base._sourceData[i]);
         base._sourceData[i] = Convolution.Instance.GaussianConv(data, std).ToByteArray2D();
     }
     double num6 = ((double) length) / ((double) base._newWidth);
     double num7 = ((double) num2) / ((double) base._newHeight);
     base._destinationData = new NNResize().Apply(base._sourceData, base._newWidth, base._newHeight);
 }
Пример #11
0
        protected override void ApplyFilter()
        {
            int    length = base._sourceData[0].GetLength(0);
            int    num2   = base._sourceData[0].GetLength(1);
            int    num3   = base._sourceData.Length;
            double std    = (length / base._newWidth) * 0.5;

            for (int i = 0; i < num3; i++)
            {
                GrayImage data = new GrayImage(base._sourceData[i]);
                base._sourceData[i] = Convolution.Instance.GaussianConv(data, std).ToByteArray2D();
            }
            double num6 = ((double)length) / ((double)base._newWidth);
            double num7 = ((double)num2) / ((double)base._newHeight);

            base._destinationData = new NNResize().Apply(base._sourceData, base._newWidth, base._newHeight);
        }
Пример #12
0
        public GrayImage Conv2DSymmetric(GrayImage data, GrayImage opLR)
        {
            int       num   = opLR.Width - 1;
            int       num2  = opLR.Height - 1;
            GrayImage image = new GrayImage(data.Width + (2 * num), data.Height + (2 * num2));
            int       index = 0;

            for (int i = 0; i < data.Height; i++)
            {
                int num5 = ((i + num2) * (data.Width + (2 * num))) + num;
                for (int j = 0; j < data.Width; j++)
                {
                    image.Scan0[num5 + j] = data.Scan0[index];
                    index++;
                }
            }
            return(this.Conv2DSymm(image, opLR));
        }
Пример #13
0
        public GrayImage Conv2DSymmetric(GrayImage data, GrayImage opLR)
        {
            int       num       = opLR.Width - 1;
            int       num2      = opLR.Height - 1;
            GrayImage grayImage = new GrayImage(data.Width + 2 * num, data.Height + 2 * num2);
            int       num3      = 0;

            for (int i = 0; i < data.Height; i++)
            {
                int num4 = (i + num2) * (data.Width + 2 * num) + num;
                for (int j = 0; j < data.Width; j++)
                {
                    grayImage.Scan0[num4 + j] = data.Scan0[num3];
                    num3++;
                }
            }
            return(Conv2DSymm(grayImage, opLR));
        }
Пример #14
0
        private GrayImage Conv2DSymm(GrayImage data, GrayImage opLR)
        {
            if (((opLR.Width % 2) != 0) || ((opLR.Height % 2) != 0))
            {
                throw new ArgumentException("Operator must have an even number of rows and columns.");
            }
            int       num   = opLR.Width - 1;
            int       num2  = opLR.Height - 1;
            GrayImage image = new GrayImage(data.Width - (2 * num), data.Height - (2 * num2));

            for (int i = num2; i < (data.Height - num2); i++)
            {
                for (int j = num; j < (data.Width - num); j++)
                {
                    float num5 = data[j, i] * opLR.Scan0[0];
                    int   num6 = 1;
                    while (num6 < opLR.Height)
                    {
                        num5 += (data[j, i + num6] + data[j, i - num6]) * opLR[0, num6];
                        num6++;
                    }
                    int num7 = 1;
                    while (num7 < opLR.Width)
                    {
                        num5 += (data[j + num7, i] + data[j - num7, i]) * opLR[num7, 0];
                        num7++;
                    }
                    int index = 1;
                    for (num6 = 1; num6 < opLR.Height; num6++)
                    {
                        int num9  = ((i + num6) * data.Width) + j;
                        int num10 = ((i - num6) * data.Width) + j;
                        for (num7 = 1; num7 < opLR.Width; num7++)
                        {
                            num5 += (((data.Scan0[num9 + num7] + data.Scan0[num10 + num7]) + data.Scan0[num9 - num7]) + data.Scan0[num10 - num7]) * opLR.Scan0[index];
                            index++;
                        }
                        index++;
                    }
                    image[j - num, i - num2] = num5;
                }
            }
            return(image);
        }
Пример #15
0
        /// <summary>
        /// Filters an GrayImage with a 1D symmetric filter along the X-axis.
        /// (This operation is multithreaded)
        /// </summary>
        /// <param name="data">GrayImage to be operated on</param>
        /// <param name="filter">Filter to use (center tap plus right-hand-side)</param>
        /// <param name="transpose">Transpose the result?</param>
        /// <returns>Transposed, filtered GrayImage.</returns>
        public GrayImage Filter1DSymmetric(GrayImage data, float[] filter, bool transpose)
        {
            GrayImage result = transpose ?
                               new GrayImage(data.Height, data.Width) :
                               new GrayImage(data.Width, data.Height);

            int startY = 0;

            int destPtr = transpose ?  startY : (startY * result.Width);

            FilterJob job
                = new FilterJob
                {
                filter  = filter,
                data    = data,
                destPtr = destPtr,
                result  = result,
                start   = startY,
                end     = data.Height / 2
                };

            ParameterizedThreadStart del = transpose ?
                                           new ParameterizedThreadStart(FilterPartSymmetricT) :
                                           new ParameterizedThreadStart(FilterPartSymmetric);

            Thread worker = new Thread(del);

            worker.Start(job);

            startY  = data.Height / 2;
            destPtr = transpose ?  startY : (startY * result.Width);


            job.start   = startY;
            job.destPtr = destPtr;
            job.end     = data.Height;

            del((object)job); // Run the appropriate filter in this thread, too

            worker.Join();


            return(result);
        }
Пример #16
0
 private GrayImage Conv2DSymm(GrayImage data, GrayImage opLR)
 {
     if (((opLR.Width % 2) != 0) || ((opLR.Height % 2) != 0))
     {
         throw new ArgumentException("Operator must have an even number of rows and columns.");
     }
     int num = opLR.Width - 1;
     int num2 = opLR.Height - 1;
     GrayImage image = new GrayImage(data.Width - (2 * num), data.Height - (2 * num2));
     for (int i = num2; i < (data.Height - num2); i++)
     {
         for (int j = num; j < (data.Width - num); j++)
         {
             float num5 = data[j, i] * opLR.Scan0[0];
             int num6 = 1;
             while (num6 < opLR.Height)
             {
                 num5 += (data[j, i + num6] + data[j, i - num6]) * opLR[0, num6];
                 num6++;
             }
             int num7 = 1;
             while (num7 < opLR.Width)
             {
                 num5 += (data[j + num7, i] + data[j - num7, i]) * opLR[num7, 0];
                 num7++;
             }
             int index = 1;
             for (num6 = 1; num6 < opLR.Height; num6++)
             {
                 int num9 = ((i + num6) * data.Width) + j;
                 int num10 = ((i - num6) * data.Width) + j;
                 for (num7 = 1; num7 < opLR.Width; num7++)
                 {
                     num5 += (((data.Scan0[num9 + num7] + data.Scan0[num10 + num7]) + data.Scan0[num9 - num7]) + data.Scan0[num10 - num7]) * opLR.Scan0[index];
                     index++;
                 }
                 index++;
             }
             image[j - num, i - num2] = num5;
         }
     }
     return image;
 }
Пример #17
0
        /// <summary>
        /// Vanilla 2D convolution.  Not optimized.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="op"></param>
        /// <returns></returns>
        public GrayImage Conv2D(GrayImage data, GrayImage op)
        {
            GrayImage result = new GrayImage(data.Width, data.Height);

            if (op.Width % 2 == 0 || op.Height % 2 == 0)
                throw new ArgumentException("Operator must have an odd number of rows and columns.");

            int x_offset = op.Width / 2;
            int y_offset = op.Height / 2;

            for (int y = 0; y < data.Height; y++)
            {
                for (int x = 0; x < data.Width; x++)
                {
                    float pixel = 0;
                    float wt = 0;

                    for (int op_y = 0; op_y < op.Height; op_y++)
                    {
                        int d_y = y - y_offset + op_y;
                        if (d_y < 0 || d_y >= data.Height) continue;

                        for (int op_x = 0; op_x < op.Width; op_x++)
                        {
                            int d_x = x - x_offset + op_x;
                            if (d_x < 0 || d_x >= data.Width) continue;

                            float op_val = op[op_x, op_y];

                            /* Perform actual convolution */
                            wt += Math.Abs(op_val);
                            pixel += data[d_x, d_y] * op_val;
                        }
                    }

                    result[x, y] = pixel / wt;

                } // loop over data x

            } // loop over data y

            return result;
        }
Пример #18
0
        public GrayImage Conv2DSymmetric(GrayImage data, GrayImage opLR)
        {
            int xPad = opLR.Width - 1;
            int yPad = opLR.Height - 1;

            GrayImage padded = new GrayImage(data.Width + 2 * xPad, data.Height + 2 * yPad);

            int dataIdx = 0;
            for (int y = 0; y < data.Height; y++)
            {
                int rowStart = (y + yPad) * (data.Width + 2 * xPad) + xPad;
                for (int x = 0; x < data.Width; x++)
                {
                    padded.Scan0[rowStart + x] = data.Scan0[dataIdx];
                    dataIdx++;
                }
            }

            return Conv2DSymm(padded, opLR);
        }
Пример #19
0
        public GrayImage Conv2DSymmetric(GrayImage data, GrayImage opLR)
        {
            int xPad = opLR.Width - 1;
            int yPad = opLR.Height - 1;

            GrayImage padded = new GrayImage(data.Width + 2 * xPad, data.Height + 2 * yPad);

            int dataIdx = 0;

            for (int y = 0; y < data.Height; y++)
            {
                int rowStart = (y + yPad) * (data.Width + 2 * xPad) + xPad;
                for (int x = 0; x < data.Width; x++)
                {
                    padded.Scan0[rowStart + x] = data.Scan0[dataIdx];
                    dataIdx++;
                }
            }

            return(Conv2DSymm(padded, opLR));
        }
Пример #20
0
        public GrayImage Conv2D(GrayImage data, GrayImage op)
        {
            GrayImage grayImage = new GrayImage(data.Width, data.Height);

            if (op.Width % 2 == 0 || op.Height % 2 == 0)
            {
                throw new ArgumentException("Operator must have an odd number of rows and columns.");
            }
            int num  = op.Width / 2;
            int num2 = op.Height / 2;

            for (int i = 0; i < data.Height; i++)
            {
                for (int j = 0; j < data.Width; j++)
                {
                    float num3 = 0f;
                    float num4 = 0f;
                    for (int k = 0; k < op.Height; k++)
                    {
                        int num5 = i - num2 + k;
                        if (num5 < 0 || num5 >= data.Height)
                        {
                            continue;
                        }
                        for (int l = 0; l < op.Width; l++)
                        {
                            int num6 = j - num + l;
                            if (num6 >= 0 && num6 < data.Width)
                            {
                                float num7 = op[l, k];
                                num4 += Math.Abs(num7);
                                num3 += data[num6, num5] * num7;
                            }
                        }
                    }
                    grayImage[j, i] = num3 / num4;
                }
            }
            return(grayImage);
        }
Пример #21
0
        public GrayImage Conv2DSymm(GrayImage data, GrayImage opLR)
        {
            if (opLR.Width % 2 != 0 || opLR.Height % 2 != 0)
            {
                throw new ArgumentException("Operator must have an even number of rows and columns.");
            }
            int       num       = opLR.Width - 1;
            int       num2      = opLR.Height - 1;
            GrayImage grayImage = new GrayImage(data.Width - 2 * num, data.Height - 2 * num2);

            for (int i = num2; i < data.Height - num2; i++)
            {
                for (int j = num; j < data.Width - num; j++)
                {
                    float num3 = data[j, i] * opLR.Scan0[0];
                    for (int k = 1; k < opLR.Height; k++)
                    {
                        num3 += (data[j, i + k] + data[j, i - k]) * opLR[0, k];
                    }
                    for (int l = 1; l < opLR.Width; l++)
                    {
                        num3 += (data[j + l, i] + data[j - l, i]) * opLR[l, 0];
                    }
                    int num4 = 1;
                    for (int m = 1; m < opLR.Height; m++)
                    {
                        int num5 = (i + m) * data.Width + j;
                        int num6 = (i - m) * data.Width + j;
                        for (int n = 1; n < opLR.Width; n++)
                        {
                            num3 += (data.Scan0[num5 + n] + data.Scan0[num6 + n] + data.Scan0[num5 - n] + data.Scan0[num6 - n]) * opLR.Scan0[num4];
                            num4++;
                        }
                        num4++;
                    }
                    grayImage[j - num, i - num2] = num3;
                }
            }
            return(grayImage);
        }
Пример #22
0
        public GrayImage Conv2D(GrayImage data, GrayImage op)
        {
            GrayImage image = new GrayImage(data.Width, data.Height);

            if (((op.Width % 2) == 0) || ((op.Height % 2) == 0))
            {
                throw new ArgumentException("Operator must have an odd number of rows and columns.");
            }
            int num  = op.Width / 2;
            int num2 = op.Height / 2;

            for (int i = 0; i < data.Height; i++)
            {
                for (int j = 0; j < data.Width; j++)
                {
                    float num5 = 0f;
                    float num6 = 0f;
                    for (int k = 0; k < op.Height; k++)
                    {
                        int num8 = (i - num2) + k;
                        if ((num8 >= 0) && (num8 < data.Height))
                        {
                            for (int m = 0; m < op.Width; m++)
                            {
                                int num10 = (j - num) + m;
                                if ((num10 >= 0) && (num10 < data.Width))
                                {
                                    float num11 = op[m, k];
                                    num6 += Math.Abs(num11);
                                    num5 += data[num10, num8] * num11;
                                }
                            }
                        }
                    }
                    image[j, i] = num5 / num6;
                }
            }
            return(image);
        }
Пример #23
0
        public GrayImage Filter1DSymmetric(GrayImage data, float[] filter, bool transpose)
        {
            GrayImage result    = transpose ? new GrayImage(data.Height, data.Width) : new GrayImage(data.Width, data.Height);
            FilterJob filterJob = default(FilterJob);

            filterJob.filter  = filter;
            filterJob.data    = data;
            filterJob.destPtr = 0;
            filterJob.result  = result;
            filterJob.start   = 0;
            filterJob.end     = data.Height;
            FilterJob filterJob2 = filterJob;

            if (transpose)
            {
                FilterPartSymmetricT(filterJob2);
            }
            else
            {
                FilterPartSymmetric(filterJob2);
            }
            return(result);
        }
Пример #24
0
 public GrayImage Conv2D(GrayImage data, GrayImage op)
 {
     GrayImage image = new GrayImage(data.Width, data.Height);
     if (((op.Width % 2) == 0) || ((op.Height % 2) == 0))
     {
         throw new ArgumentException("Operator must have an odd number of rows and columns.");
     }
     int num = op.Width / 2;
     int num2 = op.Height / 2;
     for (int i = 0; i < data.Height; i++)
     {
         for (int j = 0; j < data.Width; j++)
         {
             float num5 = 0f;
             float num6 = 0f;
             for (int k = 0; k < op.Height; k++)
             {
                 int num8 = (i - num2) + k;
                 if ((num8 >= 0) && (num8 < data.Height))
                 {
                     for (int m = 0; m < op.Width; m++)
                     {
                         int num10 = (j - num) + m;
                         if ((num10 >= 0) && (num10 < data.Width))
                         {
                             float num11 = op[m, k];
                             num6 += Math.Abs(num11);
                             num5 += data[num10, num8] * num11;
                         }
                     }
                 }
             }
             image[j, i] = num5 / num6;
         }
     }
     return image;
 }
Пример #25
0
 public GrayImage GaussianConv(GrayImage data, double std)
 {
     float[] filter = GaussianFilter(std);
     return Conv2DSeparable(data, filter);
 }
Пример #26
0
        public GrayImage Conv2DSeparable(GrayImage data, float[] filter)
        {
            GrayImage data2 = Filter1DSymmetric(data, filter, transpose: true);

            return(Filter1DSymmetric(data2, filter, transpose: true));
        }
Пример #27
0
 public GrayImage Filter1DSymmetric(GrayImage data, float[] filter, bool transpose)
 {
     GrayImage image = transpose ? new GrayImage(data.Height, data.Width) : new GrayImage(data.Width, data.Height);
     int num = 0;
     int num2 = transpose ? num : (num * image.Width);
     FilterJob job2 = new FilterJob();
     job2.filter = filter;
     job2.data = data;
     job2.destPtr = num2;
     job2.result = image;
     job2.start = num;
     job2.end = data.Height / 2;
     FilterJob parameter = job2;
     ParameterizedThreadStart start = transpose ? new ParameterizedThreadStart(this.FilterPartSymmetricT) : new ParameterizedThreadStart(this.FilterPartSymmetric);
     Thread thread = new Thread(start);
     thread.Start(parameter);
     num = data.Height / 2;
     num2 = transpose ? num : (num * image.Width);
     parameter.start = num;
     parameter.destPtr = num2;
     parameter.end = data.Height;
     start(parameter);
     thread.Join();
     return image;
 }
Пример #28
0
 public GrayImage GaussianConv(GrayImage data, double std)
 {
     float[] filter = GaussianFilter(std);
     return(Conv2DSeparable(data, filter));
 }
Пример #29
0
 public GrayImage Conv2DSymmetric(GrayImage data, GrayImage opLR)
 {
     int num = opLR.Width - 1;
     int num2 = opLR.Height - 1;
     GrayImage image = new GrayImage(data.Width + (2 * num), data.Height + (2 * num2));
     int index = 0;
     for (int i = 0; i < data.Height; i++)
     {
         int num5 = ((i + num2) * (data.Width + (2 * num))) + num;
         for (int j = 0; j < data.Width; j++)
         {
             image.Scan0[num5 + j] = data.Scan0[index];
             index++;
         }
     }
     return this.Conv2DSymm(image, opLR);
 }
Пример #30
0
 public GrayImage Conv2DSeparable(GrayImage data, float[] filter)
 {
     GrayImage image = this.Filter1DSymmetric(data, filter, true);
     return this.Filter1DSymmetric(image, filter, true);
 }
Пример #31
0
        /// <summary>
        /// Convolves an GrayImage with a 1D filter along the X-axis.
        /// </summary>
        /// <param name="filterJob">Filter operation details</param>
        private void FilterPartSymmetric(object filterJob)
        {
            FilterJob fj = (FilterJob)filterJob;

            GrayImage data = fj.data;

            float[]   srcData = data.Scan0;
            float[]   filter  = fj.filter;
            GrayImage result  = fj.result;

            float[] resData = result.Scan0;

            int pad = filter.Length - 1;

            int destPtr = fj.destPtr;

            #region Filter (no transpose)
            for (int y = fj.start; y < fj.end; y++)
            {
                int rowStart = y * data.Width;

                int ptr = fj.dataPtr + rowStart;

                // Left checked region
                for (int x = 0; x < pad; x++)
                {
                    float pixel = srcData[ptr] * filter[0];

                    // Part of the filter that fits within the GrayImage
                    for (int i = 1; i < x + 1; i++)
                    {
                        pixel += (srcData[ptr + i] + srcData[ptr - i]) * filter[i];
                    }

                    // Part of the filter that falls off the left side
                    for (int i = x + 1; i < filter.Length; i++)
                    {
                        pixel += (srcData[ptr + i] + srcData[ptr + i]) * filter[i];
                    }

                    resData[destPtr++] = pixel; ptr++;
                }

                // Unchecked region
                for (int x = pad; x < data.Width - pad; x++)
                {
                    float pixel = srcData[ptr] * filter[0];

                    for (int i = 1; i < filter.Length; i++)
                    {
                        pixel += (srcData[ptr + i] + srcData[ptr - i]) * filter[i];
                    }

                    resData[destPtr++] = pixel; ptr++;
                }

                // Right checked region
                for (int x = data.Width - pad; x < data.Width; x++)
                {
                    float pixel = srcData[ptr] * filter[0];

                    // Part of the filter that fits within the GrayImage
                    for (int i = 0; i < (data.Width - x); i++)
                    {
                        pixel += (srcData[ptr + i] + srcData[ptr - i]) * filter[i];
                    }

                    // Part of the filter that falls off the right side
                    for (int i = (data.Width - x); i < filter.Length; i++)
                    {
                        pixel += (srcData[ptr + i] + srcData[ptr - i]) * filter[i];
                    }

                    resData[destPtr++] = pixel; ptr++;
                }
            }

            #endregion
        }
Пример #32
0
        public GrayImage Conv2DSeparable(GrayImage data, float[] filter)
        {
            GrayImage image = this.Filter1DSymmetric(data, filter, true);

            return(this.Filter1DSymmetric(image, filter, true));
        }
Пример #33
0
        private void FilterPartSymmetricT(object filterJob)
        {
            FilterJob job  = (FilterJob)filterJob;
            GrayImage data = job.data;

            float[]   numArray = data.Scan0;
            float[]   filter   = job.filter;
            GrayImage result   = job.result;
            int       num      = filter.Length - 1;

            for (int i = job.start; i < job.end; i++)
            {
                float num6;
                int   num7;
                int   num3  = i * data.Width;
                int   index = num3;
                int   num5  = 0;
                while (num5 < num)
                {
                    num6 = numArray[index] * filter[0];
                    num7 = 1;
                    while (num7 < (num5 + 1))
                    {
                        num6 += (numArray[index + num7] + numArray[index - num7]) * filter[num7];
                        num7++;
                    }
                    num7 = num5 + 1;
                    while (num7 < filter.Length)
                    {
                        num6 += (numArray[index + num7] + numArray[index + num7]) * filter[num7];
                        num7++;
                    }
                    result[i, num5] = num6;
                    index++;
                    num5++;
                }
                num5 = num;
                while (num5 < (data.Width - num))
                {
                    num6 = numArray[index] * filter[0];
                    num7 = 1;
                    while (num7 < filter.Length)
                    {
                        num6 += (numArray[index + num7] + numArray[index - num7]) * filter[num7];
                        num7++;
                    }
                    result[i, num5] = num6;
                    index++;
                    num5++;
                }
                for (num5 = data.Width - num; num5 < data.Width; num5++)
                {
                    num6 = numArray[index] * filter[0];
                    num7 = 1;
                    while (num7 < (data.Width - num5))
                    {
                        num6 += (numArray[index + num7] + numArray[index - num7]) * filter[num7];
                        num7++;
                    }
                    for (num7 = data.Width - num5; num7 < filter.Length; num7++)
                    {
                        num6 += (numArray[index - num7] + numArray[index - num7]) * filter[num7];
                    }
                    result[i, num5] = num6;
                    index++;
                }
            }
        }
Пример #34
0
        private void FilterPartSymmetric(object filterJob)
        {
            FilterJob job  = (FilterJob)filterJob;
            GrayImage data = job.data;

            float[] numArray  = data.Scan0;
            float[] filter    = job.filter;
            float[] numArray3 = job.result.Scan0;
            int     num       = filter.Length - 1;
            int     destPtr   = job.destPtr;

            for (int i = job.start; i < job.end; i++)
            {
                float num7;
                int   num8;
                int   num4  = i * data.Width;
                int   index = job.dataPtr + num4;
                int   num6  = 0;
                while (num6 < num)
                {
                    num7 = numArray[index] * filter[0];
                    num8 = 1;
                    while (num8 < (num6 + 1))
                    {
                        num7 += (numArray[index + num8] + numArray[index - num8]) * filter[num8];
                        num8++;
                    }
                    num8 = num6 + 1;
                    while (num8 < filter.Length)
                    {
                        num7 += (numArray[index + num8] + numArray[index + num8]) * filter[num8];
                        num8++;
                    }
                    numArray3[destPtr++] = num7;
                    index++;
                    num6++;
                }
                num6 = num;
                while (num6 < (data.Width - num))
                {
                    num7 = numArray[index] * filter[0];
                    num8 = 1;
                    while (num8 < filter.Length)
                    {
                        num7 += (numArray[index + num8] + numArray[index - num8]) * filter[num8];
                        num8++;
                    }
                    numArray3[destPtr++] = num7;
                    index++;
                    num6++;
                }
                for (num6 = data.Width - num; num6 < data.Width; num6++)
                {
                    num7 = numArray[index] * filter[0];
                    num8 = 0;
                    while (num8 < (data.Width - num6))
                    {
                        num7 += (numArray[index + num8] + numArray[index - num8]) * filter[num8];
                        num8++;
                    }
                    for (num8 = data.Width - num6; num8 < filter.Length; num8++)
                    {
                        num7 += (numArray[index + num8] + numArray[index - num8]) * filter[num8];
                    }
                    numArray3[destPtr++] = num7;
                    index++;
                }
            }
        }
Пример #35
0
        /// <summary>
        /// Convolves an GrayImage with a 2D-symmetric operator.
        /// </summary>
        /// <param name="data">Data to be convolved with the operator</param>
        /// <param name="opUL">Lower-right quadrant of the operator.</param>
        /// <returns></returns>
        private GrayImage Conv2DSymm(GrayImage data, GrayImage opLR)
        {
            if (opLR.Width % 2 != 0 || opLR.Height % 2 != 0)
                throw new ArgumentException("Operator must have an even number of rows and columns.");

            int xPad = opLR.Width - 1;
            int yPad = opLR.Height - 1;

            GrayImage result = new GrayImage(data.Width - 2 * xPad, data.Height - 2 * yPad);

            for (int y = yPad; y < data.Height - yPad; y++)
            {
                for (int x = xPad; x < data.Width - xPad; x++)
                {
                    // Center pixel
                    float pixel = data[x, y] * opLR.Scan0[0];

                    // Vertical center
                    for (int op_y = 1; op_y < opLR.Height; op_y++)
                        pixel += (data[x, y + op_y] + data[x, y - op_y]) * opLR[0, op_y];

                    //Horizontal center
                    for (int op_x = 1; op_x < opLR.Width; op_x++)
                        pixel += (data[x + op_x, y] + data[x - op_x, y]) * opLR[op_x, 0];

                    //Quadrants
                    int opIdx = 1;

                    for (int op_y = 1; op_y < opLR.Height; op_y++)
                    {
                        int baseIdx1 = ((y + op_y) * data.Width) + x;
                        int baseIdx2 = ((y - op_y) * data.Width) + x;

                        // Loop unrolling can save 25% execution time here

                        for (int op_x = 1; op_x < opLR.Width; op_x++)
                        {
                            pixel += (data.Scan0[baseIdx1 + op_x] +
                                      data.Scan0[baseIdx2 + op_x] +
                                      data.Scan0[baseIdx1 - op_x] +
                                      data.Scan0[baseIdx2 - op_x]) * opLR.Scan0[opIdx];

                            opIdx++;
                        }

                        opIdx++; // Skip 0th col on next row
                    }

                    result[x - xPad, y - yPad] = pixel;

                } // loop over data x

            } // loop over data y

            return result;
        }