private unsafe void ProcessFilter(UnmanagedImage dstImage, UnmanagedImage srcImage)
        {
            IntPoint point;
            IntPoint point2;
            int      width  = srcImage.Width;
            int      height = srcImage.Height;
            int      num3   = dstImage.Width;
            int      num4   = dstImage.Height;
            int      num5   = Image.GetPixelFormatSize(srcImage.PixelFormat) / 8;
            int      stride = srcImage.Stride;
            int      num7   = dstImage.Stride;

            PointsCloud.GetBoundingRectangle(this.destinationQuadrilateral, ref point, ref point2);
            if (((point2.X >= 0) && (point2.Y >= 0)) && ((point.X < num3) && (point.Y < num4)))
            {
                if (point.X < 0)
                {
                    point.X = 0;
                }
                if (point.Y < 0)
                {
                    point.Y = 0;
                }
                if (point2.X >= num3)
                {
                    point2.X = num3 - 1;
                }
                if (point2.Y >= num4)
                {
                    point2.Y = num4 - 1;
                }
                int             x      = point.X;
                int             y      = point.Y;
                int             num10  = point2.X + 1;
                int             num11  = point2.Y + 1;
                int             num12  = num7 - ((num10 - x) * num5);
                List <IntPoint> output = new List <IntPoint> {
                    new IntPoint(0, 0),
                    new IntPoint(width - 1, 0),
                    new IntPoint(width - 1, height - 1),
                    new IntPoint(0, height - 1)
                };
                double[,] numArray = QuadTransformationCalcs.MapQuadToQuad(this.destinationQuadrilateral, output);
                byte *numPtr  = (byte *)dstImage.ImageData.ToPointer();
                byte *numPtr2 = (byte *)srcImage.ImageData.ToPointer();
                numPtr += (y * num7) + (x * num5);
                if (!this.useInterpolation)
                {
                    for (int i = y; i < num11; i++)
                    {
                        for (int j = x; j < num10; j++)
                        {
                            double num15 = ((numArray[2, 0] * j) + (numArray[2, 1] * i)) + numArray[2, 2];
                            double num16 = (((numArray[0, 0] * j) + (numArray[0, 1] * i)) + numArray[0, 2]) / num15;
                            double num17 = (((numArray[1, 0] * j) + (numArray[1, 1] * i)) + numArray[1, 2]) / num15;
                            if (((num16 >= 0.0) && (num17 >= 0.0)) && ((num16 < width) && (num17 < height)))
                            {
                                byte *numPtr3 = (numPtr2 + (((int)num17) * stride)) + (((int)num16) * num5);
                                int   num18   = 0;
                                while (num18 < num5)
                                {
                                    numPtr[0] = numPtr3[0];
                                    num18++;
                                    numPtr++;
                                    numPtr3++;
                                }
                            }
                            else
                            {
                                numPtr += num5;
                            }
                        }
                        numPtr += num12;
                    }
                }
                else
                {
                    int num19 = width - 1;
                    int num20 = height - 1;
                    for (int k = y; k < num11; k++)
                    {
                        for (int m = x; m < num10; m++)
                        {
                            double num31 = ((numArray[2, 0] * m) + (numArray[2, 1] * k)) + numArray[2, 2];
                            double num32 = (((numArray[0, 0] * m) + (numArray[0, 1] * k)) + numArray[0, 2]) / num31;
                            double num33 = (((numArray[1, 0] * m) + (numArray[1, 1] * k)) + numArray[1, 2]) / num31;
                            if (((num32 >= 0.0) && (num33 >= 0.0)) && ((num32 < width) && (num33 < height)))
                            {
                                byte * numPtr5;
                                byte * numPtr7;
                                int    num25   = (int)num32;
                                int    num27   = (num25 == num19) ? num25 : (num25 + 1);
                                double num21   = num32 - num25;
                                double num23   = 1.0 - num21;
                                int    num26   = (int)num33;
                                int    num28   = (num26 == num20) ? num26 : (num26 + 1);
                                double num22   = num33 - num26;
                                double num24   = 1.0 - num22;
                                byte * numPtr4 = numPtr5 = numPtr2 + (num26 * stride);
                                numPtr4 += num25 * num5;
                                numPtr5 += num27 * num5;
                                byte *numPtr6 = numPtr7 = numPtr2 + (num28 * stride);
                                numPtr6 += num25 * num5;
                                numPtr7 += num27 * num5;
                                int num34 = 0;
                                while (num34 < num5)
                                {
                                    numPtr[0] = (byte)((num24 * ((num23 * numPtr4[0]) + (num21 * numPtr5[0]))) + (num22 * ((num23 * numPtr6[0]) + (num21 * numPtr7[0]))));
                                    num34++;
                                    numPtr++;
                                    numPtr4++;
                                    numPtr5++;
                                    numPtr6++;
                                    numPtr7++;
                                }
                            }
                            else
                            {
                                numPtr += num5;
                            }
                        }
                        numPtr += num12;
                    }
                }
            }
        }
        /// <summary>
        /// Process the filter on the specified image.
        /// </summary>
        ///
        /// <param name="sourceData">Source image data.</param>
        /// <param name="destinationData">Destination image data.</param>
        ///
        protected override unsafe void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData)
        {
            // get source and destination images size
            int srcWidth  = sourceData.Width;
            int srcHeight = sourceData.Height;
            int dstWidth  = destinationData.Width;
            int dstHeight = destinationData.Height;

            int pixelSize = Image.GetPixelFormatSize(sourceData.PixelFormat) / 8;
            int srcStride = sourceData.Stride;
            int dstStride = destinationData.Stride;
            int offset    = dstStride - dstWidth * pixelSize;

            // calculate tranformation matrix
            List <IntPoint> dstRect = new List <IntPoint>( );

            dstRect.Add(new IntPoint(0, 0));
            dstRect.Add(new IntPoint(dstWidth - 1, 0));
            dstRect.Add(new IntPoint(dstWidth - 1, dstHeight - 1));
            dstRect.Add(new IntPoint(0, dstHeight - 1));

            // calculate tranformation matrix
            double[,] matrix = QuadTransformationCalcs.MapQuadToQuad(dstRect, sourceQuadrilateral);

            // do the job
            byte *ptr     = (byte *)destinationData.ImageData.ToPointer( );
            byte *baseSrc = (byte *)sourceData.ImageData.ToPointer( );

            if (!useInterpolation)
            {
                byte *p;

                // for each row
                for (int y = 0; y < dstHeight; y++)
                {
                    // for each pixel
                    for (int x = 0; x < dstWidth; x++)
                    {
                        double factor = matrix[2, 0] * x + matrix[2, 1] * y + matrix[2, 2];
                        double srcX   = (matrix[0, 0] * x + matrix[0, 1] * y + matrix[0, 2]) / factor;
                        double srcY   = (matrix[1, 0] * x + matrix[1, 1] * y + matrix[1, 2]) / factor;

                        if ((srcX >= 0) && (srcY >= 0) && (srcX < srcWidth) && (srcY < srcHeight))
                        {
                            // get pointer to the pixel in the source image
                            p = baseSrc + (int)srcY * srcStride + (int)srcX * pixelSize;
                            // copy pixel's values
                            for (int i = 0; i < pixelSize; i++, ptr++, p++)
                            {
                                *ptr = *p;
                            }
                        }
                        else
                        {
                            ptr += pixelSize;
                        }
                    }
                    ptr += offset;
                }
            }
            else
            {
                int srcWidthM1  = srcWidth - 1;
                int srcHeightM1 = srcHeight - 1;

                // coordinates of source points
                double dx1, dy1, dx2, dy2;
                int    sx1, sy1, sx2, sy2;

                // temporary pointers
                byte *p1, p2, p3, p4;

                // for each row
                for (int y = 0; y < dstHeight; y++)
                {
                    // for each pixel
                    for (int x = 0; x < dstWidth; x++)
                    {
                        double factor = matrix[2, 0] * x + matrix[2, 1] * y + matrix[2, 2];
                        double srcX   = (matrix[0, 0] * x + matrix[0, 1] * y + matrix[0, 2]) / factor;
                        double srcY   = (matrix[1, 0] * x + matrix[1, 1] * y + matrix[1, 2]) / factor;

                        if ((srcX >= 0) && (srcY >= 0) && (srcX < srcWidth) && (srcY < srcHeight))
                        {
                            sx1 = (int)srcX;
                            sx2 = (sx1 == srcWidthM1) ? sx1 : sx1 + 1;
                            dx1 = srcX - sx1;
                            dx2 = 1.0 - dx1;

                            sy1 = (int)srcY;
                            sy2 = (sy1 == srcHeightM1) ? sy1 : sy1 + 1;
                            dy1 = srcY - sy1;
                            dy2 = 1.0 - dy1;

                            // get four points
                            p1  = p2 = baseSrc + sy1 * srcStride;
                            p1 += sx1 * pixelSize;
                            p2 += sx2 * pixelSize;

                            p3  = p4 = baseSrc + sy2 * srcStride;
                            p3 += sx1 * pixelSize;
                            p4 += sx2 * pixelSize;

                            // interpolate using 4 points
                            for (int i = 0; i < pixelSize; i++, ptr++, p1++, p2++, p3++, p4++)
                            {
                                *ptr = (byte)(
                                    dy2 * (dx2 * (*p1) + dx1 * (*p2)) +
                                    dy1 * (dx2 * (*p3) + dx1 * (*p4)));
                            }
                        }
                        else
                        {
                            ptr += pixelSize;
                        }
                    }
                    ptr += offset;
                }
            }
        }
Ejemplo n.º 3
0
        // Process both images transforming source image into quadrilateral in destination image
        private unsafe void ProcessFilter(UnmanagedImage dstImage, UnmanagedImage srcImage)
        {
            // get source and destination images size
            int srcWidth  = srcImage.Width;
            int srcHeight = srcImage.Height;
            int dstWidth  = dstImage.Width;
            int dstHeight = dstImage.Height;

            int pixelSize = Image.GetPixelFormatSize(srcImage.PixelFormat) / 8;
            int srcStride = srcImage.Stride;
            int dstStride = dstImage.Stride;

            // get bounding rectangle of the quadrilateral
            IntPoint minXY, maxXY;

            PointsCloud.GetBoundingRectangle(destinationQuadrilateral, out minXY, out maxXY);

            // make sure the rectangle is inside of destination image
            if ((maxXY.X < 0) || (maxXY.Y < 0) || (minXY.X >= dstWidth) || (minXY.Y >= dstHeight))
            {
                return; // nothing to do, since quadrilateral is completely outside
            }
            // correct rectangle if required
            if (minXY.X < 0)
            {
                minXY.X = 0;
            }
            if (minXY.Y < 0)
            {
                minXY.Y = 0;
            }
            if (maxXY.X >= dstWidth)
            {
                maxXY.X = dstWidth - 1;
            }
            if (maxXY.Y >= dstHeight)
            {
                maxXY.Y = dstHeight - 1;
            }

            int startX = minXY.X;
            int startY = minXY.Y;
            int stopX  = maxXY.X + 1;
            int stopY  = maxXY.Y + 1;
            int offset = dstStride - (stopX - startX) * pixelSize;

            // calculate tranformation matrix
            List <IntPoint> srcRect = new List <IntPoint>( );

            srcRect.Add(new IntPoint(0, 0));
            srcRect.Add(new IntPoint(srcWidth - 1, 0));
            srcRect.Add(new IntPoint(srcWidth - 1, srcHeight - 1));
            srcRect.Add(new IntPoint(0, srcHeight - 1));

            double[,] matrix = QuadTransformationCalcs.MapQuadToQuad(destinationQuadrilateral, srcRect);

            // do the job
            byte *ptr     = (byte *)dstImage.ImageData.ToPointer( );
            byte *baseSrc = (byte *)srcImage.ImageData.ToPointer( );

            // allign pointer to the first pixel to process
            ptr += (startY * dstStride + startX * pixelSize);

            if (!useInterpolation)
            {
                byte *p;

                // for each row
                for (int y = startY; y < stopY; y++)
                {
                    // for each pixel
                    for (int x = startX; x < stopX; x++)
                    {
                        double factor = matrix[2, 0] * x + matrix[2, 1] * y + matrix[2, 2];
                        double srcX   = (matrix[0, 0] * x + matrix[0, 1] * y + matrix[0, 2]) / factor;
                        double srcY   = (matrix[1, 0] * x + matrix[1, 1] * y + matrix[1, 2]) / factor;

                        if ((srcX >= 0) && (srcY >= 0) && (srcX < srcWidth) && (srcY < srcHeight))
                        {
                            // get pointer to the pixel in the source image
                            p = baseSrc + (int)srcY * srcStride + (int)srcX * pixelSize;
                            // copy pixel's values
                            for (int i = 0; i < pixelSize; i++, ptr++, p++)
                            {
                                *ptr = *p;
                            }
                        }
                        else
                        {
                            // skip the pixel
                            ptr += pixelSize;
                        }
                    }
                    ptr += offset;
                }
            }
            else
            {
                int srcWidthM1  = srcWidth - 1;
                int srcHeightM1 = srcHeight - 1;

                // coordinates of source points
                double dx1, dy1, dx2, dy2;
                int    sx1, sy1, sx2, sy2;

                // temporary pointers
                byte *p1, p2, p3, p4;

                // for each row
                for (int y = startY; y < stopY; y++)
                {
                    // for each pixel
                    for (int x = startX; x < stopX; x++)
                    {
                        double factor = matrix[2, 0] * x + matrix[2, 1] * y + matrix[2, 2];
                        double srcX   = (matrix[0, 0] * x + matrix[0, 1] * y + matrix[0, 2]) / factor;
                        double srcY   = (matrix[1, 0] * x + matrix[1, 1] * y + matrix[1, 2]) / factor;

                        if ((srcX >= 0) && (srcY >= 0) && (srcX < srcWidth) && (srcY < srcHeight))
                        {
                            sx1 = (int)srcX;
                            sx2 = (sx1 == srcWidthM1) ? sx1 : sx1 + 1;
                            dx1 = srcX - sx1;
                            dx2 = 1.0 - dx1;

                            sy1 = (int)srcY;
                            sy2 = (sy1 == srcHeightM1) ? sy1 : sy1 + 1;
                            dy1 = srcY - sy1;
                            dy2 = 1.0 - dy1;

                            // get four points
                            p1  = p2 = baseSrc + sy1 * srcStride;
                            p1 += sx1 * pixelSize;
                            p2 += sx2 * pixelSize;

                            p3  = p4 = baseSrc + sy2 * srcStride;
                            p3 += sx1 * pixelSize;
                            p4 += sx2 * pixelSize;

                            // interpolate using 4 points
                            for (int i = 0; i < pixelSize; i++, ptr++, p1++, p2++, p3++, p4++)
                            {
                                *ptr = (byte)(
                                    dy2 * (dx2 * (*p1) + dx1 * (*p2)) +
                                    dy1 * (dx2 * (*p3) + dx1 * (*p4)));
                            }
                        }
                        else
                        {
                            // skip the pixel
                            ptr += pixelSize;
                        }
                    }
                    ptr += offset;
                }
            }
        }