AForge.Imaging.Filters.BackwardQuadrilateralTransformation.ProcessFilter C# (CSharp) Метод

ProcessFilter() приватный Метод

private ProcessFilter ( UnmanagedImage dstImage, UnmanagedImage srcImage ) : void
dstImage UnmanagedImage
srcImage UnmanagedImage
Результат void
        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;
                }
            }
        }
    }

Same methods

BackwardQuadrilateralTransformation::ProcessFilter ( UnmanagedImage image ) : void
BackwardQuadrilateralTransformation