Example #1
0
        public static void DoMatch(ImageBufferFloat imageToSearch, ImageBufferFloat imageToFind, ImageBufferFloat result)
        {
            result = new ImageBufferFloat(imageToSearch.Width, imageToSearch.Height, 32, new BlenderBGRAFloat());
            if (imageToSearch.Width >= imageToFind.Width &&
                imageToSearch.Height >= imageToFind.Height &&
                imageToSearch.BitDepth == imageToFind.BitDepth)
            {
                int     floatsPerPixel = imageToSearch.BitDepth / 32;
                int     searchDistanceBetweenPixels = imageToSearch.GetFloatsBetweenPixelsInclusive();
                int     findDistanceBetweenPixels   = imageToFind.GetFloatsBetweenPixelsInclusive();
                float[] searchBuffer       = imageToSearch.GetBuffer();
                float[] findBuffer         = imageToFind.GetBuffer();
                float[] resultBuffer       = imageToFind.GetBuffer();
                int     resutsBufferOffset = 0;
                for (int matchY = 0; matchY <= imageToSearch.Height - imageToFind.Height; matchY++)
                {
                    for (int matchX = 0; matchX <= imageToSearch.Width - imageToFind.Width; matchX++)
                    {
                        double currentLeastSquares = 0;

                        for (int imageToFindY = 0; imageToFindY < imageToFind.Height; imageToFindY++)
                        {
                            int searchBufferOffset = imageToSearch.GetBufferOffsetXY(matchX, matchY + imageToFindY);
                            int findBufferOffset   = imageToFind.GetBufferOffsetY(imageToFindY);
                            for (int findX = 0; findX < imageToFind.Width; findX++)
                            {
                                for (int byteIndex = 0; byteIndex < floatsPerPixel; byteIndex++)
                                {
                                    float aByte      = searchBuffer[searchBufferOffset + byteIndex];
                                    float bByte      = findBuffer[findBufferOffset + byteIndex];
                                    int   difference = (int)aByte - (int)bByte;
                                    currentLeastSquares += difference * difference;
                                }
                                searchBufferOffset += searchDistanceBetweenPixels;
                                findBufferOffset   += findDistanceBetweenPixels;
                            }
                        }

                        resultBuffer[resutsBufferOffset] = (float)currentLeastSquares;
                        resutsBufferOffset++;
                    }
                }
            }
        }
        public void CreateLineSegments()
        {
            LineSegments.Clear();
            float[] buffer         = imageToMarch.GetBuffer();
            int     strideInFloats = imageToMarch.StrideInFloats();

            for (int y = 0; y < imageToMarch.Height - 1; y++)
            {
                int offset = imageToMarch.GetBufferOffsetY(y);
                for (int x = 0; x < imageToMarch.Width - 1; x++)
                {
                    int   offsetWithX = offset + x;
                    float point0      = buffer[offsetWithX + strideInFloats];
                    float point1      = buffer[offsetWithX + 1 + strideInFloats];
                    float point2      = buffer[offsetWithX + 1];
                    float point3      = buffer[offsetWithX];
                    int   flags       = (point0 > threshold) ? 1 : 0;
                    flags = (flags << 1) | ((point1 > threshold) ? 1 : 0);
                    flags = (flags << 1) | ((point2 > threshold) ? 1 : 0);
                    flags = (flags << 1) | ((point3 > threshold) ? 1 : 0);

                    bool wasFlipped = false;
                    if (flags == 5)
                    {
                        float average = (point0 + point1 + point2 + point3) / 4;
                        if (average < threshold)
                        {
                            flags      = 10;
                            wasFlipped = true;
                        }
                    }
                    else if (flags == 10)
                    {
                        float average = (point0 + point1 + point2 + point3) / 4;
                        if (average < threshold)
                        {
                            flags      = 5;
                            wasFlipped = true;
                        }
                    }

                    AddSegmentForFlags(x, y, flags, wasFlipped);
                }
            }
        }
        internal void UpdateHardwareSurface(RectangleInt rect)
        {
            numInFunction++;
            if (backingImageBufferByte != null)
            {
                if (!externallyLocked && !currentlyLocked)
                {
                    currentlyLocked = true;
                    bitmapData      = windowsBitmap.LockBits(new Rectangle(0, 0, windowsBitmap.Width, windowsBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, windowsBitmap.PixelFormat);
                }
                int    backBufferStrideInBytes  = backingImageBufferByte.StrideInBytes();
                int    backBufferStrideInInts   = backBufferStrideInBytes / 4;
                int    backBufferHeight         = backingImageBufferByte.Height;
                int    backBufferHeightMinusOne = backBufferHeight - 1;
                int    bitmapDataStride         = bitmapData.Stride;
                int    offset;
                byte[] buffer = backingImageBufferByte.GetBuffer(out offset);
                switch (backingImageBufferByte.BitDepth)
                {
                case 24:
                {
                    unsafe
                    {
                        byte *bitmapDataScan0 = (byte *)bitmapData.Scan0;
                        fixed(byte *pSourceFixed = &buffer[offset])
                        {
                            byte *pSource     = pSourceFixed;
                            byte *pDestBuffer = bitmapDataScan0 + bitmapDataStride * backBufferHeightMinusOne;

                            for (int y = 0; y < backBufferHeight; y++)
                            {
                                int *pSourceInt     = (int *)pSource;
                                int *pDestBufferInt = (int *)pDestBuffer;
                                for (int x = 0; x < backBufferStrideInInts; x++)
                                {
                                    pDestBufferInt[x] = pSourceInt[x];
                                }
                                for (int x = backBufferStrideInInts * 4; x < backBufferStrideInBytes; x++)
                                {
                                    pDestBuffer[x] = pSource[x];
                                }
                                pDestBuffer -= bitmapDataStride;
                                pSource     += backBufferStrideInBytes;
                            }
                        }
                    }
                }
                break;

                case 32:
                {
                    unsafe
                    {
                        byte *bitmapDataScan0 = (byte *)bitmapData.Scan0;
                        fixed(byte *pSourceFixed = &buffer[offset])
                        {
                            byte *pSource     = pSourceFixed;
                            byte *pDestBuffer = bitmapDataScan0 + bitmapDataStride * backBufferHeightMinusOne;

                            for (int y = rect.Bottom; y < rect.Top; y++)
                            {
                                int *pSourceInt = (int *)pSource;
                                pSourceInt += (backBufferStrideInBytes * y / 4);

                                int *pDestBufferInt = (int *)pDestBuffer;
                                pDestBufferInt -= (bitmapDataStride * y / 4);

                                for (int x = rect.Left; x < rect.Right; x++)
                                {
                                    pDestBufferInt[x] = pSourceInt[x];
                                }
                            }
                        }
                    }
                }
                break;

                default:
                    throw new NotImplementedException();
                }
                if (!externallyLocked)
                {
                    windowsBitmap.UnlockBits(bitmapData);
                    currentlyLocked = false;
                }
            }
            else
            {
                switch (backingImageBufferFloat.BitDepth)
                {
                case 128:
                {
                    BitmapData bitmapData = windowsBitmap.LockBits(new Rectangle(0, 0, windowsBitmap.Width, windowsBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, windowsBitmap.PixelFormat);
                    int        index      = 0;
                    unsafe
                    {
                        unchecked
                        {
                            int     offset;
                            float[] buffer = backingImageBufferFloat.GetBuffer(out offset);
                            fixed(float *pSource = &buffer[offset])
                            {
                                for (int y = 0; y < backingImageBufferFloat.Height; y++)
                                {
                                    byte *pDestBuffer = (byte *)bitmapData.Scan0 + (bitmapData.Stride * (backingImageBufferFloat.Height - 1 - y));
                                    for (int x = 0; x < backingImageBufferFloat.Width; x++)
                                    {
#if true
                                        pDestBuffer[x * 4 + 0] = (byte)(pSource[index * 4 + 0] * 255);
                                        pDestBuffer[x * 4 + 1] = (byte)(pSource[index * 4 + 1] * 255);
                                        pDestBuffer[x * 4 + 2] = (byte)(pSource[index * 4 + 2] * 255);
                                        pDestBuffer[x * 4 + 3] = (byte)(pSource[index * 4 + 3] * 255);
                                        index++;
#else
                                        pDestBuffer[x * 4 + 0] = (byte)255;
                                        pDestBuffer[x * 4 + 1] = (byte)0;
                                        pDestBuffer[x * 4 + 2] = (byte)128;
                                        pDestBuffer[x * 4 + 3] = (byte)255;
#endif
                                    }
                                }
                            }
                        }
                    }

                    windowsBitmap.UnlockBits(bitmapData);
                }
                break;

                default:
                    throw new NotImplementedException();
                }
            }

            numInFunction--;
        }