The method does complete cloning of the object.
/// <summary> /// Get rectangle contain object in current frame /// </summary> /// <param name="templateInfo">Tracking template information</param> /// <param name="source">Frame</param> /// <returns>Rectangle contain object</returns> public static Rectangle TemplateColorTracking(ImageStatistics templateInfo, ref UnmanagedImage source) { UnmanagedImage image = source.Clone(); // create filter EuclideanColorFiltering filter = new EuclideanColorFiltering(); // set center colol and radius filter.CenterColor = new RGB( (byte)templateInfo.Red.Mean, (byte)templateInfo.Green.Mean, (byte)templateInfo.Blue.Mean); filter.Radius = 30; // apply the filter filter.ApplyInPlace(image); image = Grayscale.CommonAlgorithms.BT709.Apply(image); OtsuThreshold threshold = new OtsuThreshold(); threshold.ApplyInPlace(image); BlobCounter blobCounter = new BlobCounter(); blobCounter.ObjectsOrder = ObjectsOrder.Size; blobCounter.ProcessImage(image); Rectangle rect = blobCounter.ObjectsCount > 0 ? blobCounter.GetObjectsRectangles()[0] : Rectangle.Empty; return rect; }
/// <summary> /// Perform color dithering for the specified image. /// </summary> /// /// <param name="sourceImage">Source image to do color dithering for.</param> /// /// <returns>Returns color dithered image. See <see cref="ColorTable"/> for information about format of /// the result image.</returns> /// /// <exception cref="UnsupportedImageFormatException">Unsupported pixel format of the source image. It must 24 or 32 bpp color image.</exception> /// public unsafe Bitmap Apply( UnmanagedImage sourceImage ) { if ( ( sourceImage.PixelFormat != PixelFormat.Format24bppRgb ) && ( sourceImage.PixelFormat != PixelFormat.Format32bppRgb ) && ( sourceImage.PixelFormat != PixelFormat.Format32bppArgb ) && ( sourceImage.PixelFormat != PixelFormat.Format32bppPArgb ) ) { throw new UnsupportedImageFormatException( "Unsupported pixel format of the source image." ); } cache.Clear( ); // make a copy of the original image UnmanagedImage source = sourceImage.Clone( ); // get image size width = sourceImage.Width; height = sourceImage.Height; stride = sourceImage.Stride; pixelSize = Bitmap.GetPixelFormatSize( sourceImage.PixelFormat ) / 8; int offset = stride - width * pixelSize; // create destination image Bitmap destImage = new Bitmap( width, height, ( colorTable.Length > 16 ) ? PixelFormat.Format8bppIndexed : PixelFormat.Format4bppIndexed ); // and init its palette ColorPalette cp = destImage.Palette; for ( int i = 0, n = colorTable.Length; i < n; i++ ) { cp.Entries[i] = colorTable[i]; } destImage.Palette = cp; // lock destination image BitmapData destData = destImage.LockBits( new Rectangle( 0, 0, width, height ), ImageLockMode.ReadWrite, destImage.PixelFormat ); // pixel values int r, g, b; // do the job byte* ptr = (byte*) source.ImageData.ToPointer( ); byte* dstBase = (byte*) destData.Scan0.ToPointer( ); byte colorIndex; bool is8bpp = ( colorTable.Length > 16 ); // for each line for ( y = 0; y < height; y++ ) { byte* dst = dstBase + y * destData.Stride; // for each pixels for ( x = 0; x < width; x++, ptr += pixelSize ) { r = ptr[RGB.R]; g = ptr[RGB.G]; b = ptr[RGB.B]; // get color from palette, which is the closest to current pixel's value Color closestColor = GetClosestColor( r, g, b, out colorIndex ); // do error diffusion Diffuse( r - closestColor.R, g - closestColor.G, b - closestColor.B, ptr ); // write color index as pixel's value to destination image if ( is8bpp ) { *dst = colorIndex; dst++; } else { if ( x % 2 == 0 ) { *dst |= (byte) ( colorIndex << 4 ); } else { *dst |= ( colorIndex ); dst++; } } } ptr += offset; } destImage.UnlockBits( destData ); source.Dispose( ); return destImage; }
/// <summary> /// Process the filter on the specified image. /// </summary> /// /// <param name="sourceData">Source image data.</param> /// <param name="destinationData">Destination image data.</param> /// protected unsafe override void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData) { int width = sourceData.Width; int height = sourceData.Height; PixelFormat format = sourceData.PixelFormat; int pixelSize = System.Drawing.Bitmap.GetPixelFormatSize(format) / 8; sourceData.Clone(); UnmanagedImage temp = UnmanagedImage.Create(width, height, format); int lineWidth = width * pixelSize; int srcStride = temp.Stride; int srcOffset = srcStride - lineWidth; int dstStride = destinationData.Stride; int dstOffset = dstStride - lineWidth; byte* srcStart = (byte*)temp.ImageData.ToPointer(); byte* dstStart = (byte*)destinationData.ImageData.ToPointer(); // first Convolution c = new Convolution(masks[0]); c.Apply(sourceData, destinationData); // others for (int i = 1; i < masks.Length; i++) { c.Kernel = masks[i]; c.Apply(sourceData, temp); byte* src = srcStart; byte* dst = dstStart; for (int y = 0; y < height; y++) { for (int x = 0; x < lineWidth; x++, src++, dst++) { if (*src > *dst) *dst = *src; } dst += dstOffset; src += srcOffset; } } }
public static Bitmap MatrixBlend(UnmanagedImage uOriginal, Bitmap compare, byte alpha) { //ref: http://ithoughthecamewithyou.com/post/Fastest-image-merge-(alpha-blend)-in-GDI2b.aspx string cacheKey = string.Format("MB_{0}", alpha); Stopwatch sw = new Stopwatch(); sw.Start(); // for the matrix the range is 0.0 - 1.0 float alphaNorm = (float)alpha / 255.0F; // just change the alpha ColorMatrix matrix = new ColorMatrix(new float[][]{ new float[] {1F, 0, 0, 0, 0}, new float[] {0, 1F, 0, 0, 0}, new float[] {0, 0, 1F, 0, 0}, new float[] {0, 0, 0, alphaNorm, 0}, new float[] {0, 0, 0, 0, 1F}}); ImageAttributes imageAttributes = new ImageAttributes(); imageAttributes.SetColorMatrix(matrix); //create a blank bitmap the same size as original Bitmap newBitmap = uOriginal.Clone().ToManagedImage(); sw.Stop(); _logger.Trace("MatrixBlend_newBitmap [{0}] takes {1}", cacheKey, sw.Elapsed.ToString()); sw.Restart(); //get a graphics object from the new image using (Graphics g = Graphics.FromImage(newBitmap)) { g.CompositingMode = CompositingMode.SourceOver; g.CompositingQuality = CompositingQuality.HighSpeed; g.DrawImage(compare, new Rectangle(0, 0, uOriginal.Width, uOriginal.Height), 0, 0, compare.Width, compare.Height, GraphicsUnit.Pixel, imageAttributes); } sw.Stop(); _logger.Trace("MatrixBlend_drawImage [{0}] takes {1}", cacheKey, sw.Elapsed.ToString()); return newBitmap; }