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--; }