/// <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 void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData) { if (sourceData.PixelFormat == PixelFormat.Format8bppIndexed) { sourceData = toRGB.Apply(sourceData); } // Copy image contents sourceData.Copy(destinationData); Bitmap managedImage = destinationData.ToManagedImage(makeCopy: false); using (Graphics g = Graphics.FromImage(managedImage)) using (Pen positive = new Pen(Color.Red)) using (Pen negative = new Pen(Color.Blue)) using (Pen line = new Pen(Color.FromArgb(0, 255, 0))) { // mark all points foreach (SpeededUpRobustFeaturePoint p in points) { int S = (int)(scale * p.Scale); int R = (int)(S / 2f); Point pt = new Point((int)p.X, (int)p.Y); Point ptR = new Point((int)(R * System.Math.Cos(p.Orientation)), (int)(R * System.Math.Sin(p.Orientation))); Pen myPen = (p.Laplacian > 0 ? negative : positive); g.DrawEllipse(myPen, pt.X - R, pt.Y - R, S, S); g.DrawLine(line, new Point(pt.X, pt.Y), new Point(pt.X + ptR.X, pt.Y + ptR.Y)); } } }
/// <summary> /// Process the filter on the specified image. /// </summary> /// /// <param name="sourceData">Source image data.</param> /// <param name="destinationData">Destination image data.</param> /// /// <exception cref="InvalidImagePropertiesException">Texture size does not match image size.</exception> /// <exception cref="ApplicationException">Filters should not change image dimension.</exception> /// protected override unsafe void ProcessFilter(UnmanagedImage sourceData, UnmanagedImage destinationData) { // get source image dimension int width = sourceData.Width; int height = sourceData.Height; // if generator was specified, then generate a texture // otherwise use provided texture if (textureGenerator != null) { texture = textureGenerator.Generate(width, height); } else { // check existing texture if ((texture.GetLength(0) != height) || (texture.GetLength(1) != width)) { // sorry, but source image must have the same dimension as texture throw new InvalidImagePropertiesException("Texture size does not match image size."); } } // apply first filter UnmanagedImage filteredImage1 = filter1.Apply(sourceData); // check size of the result image if ((width != filteredImage1.Width) || (height != filteredImage1.Height)) { filteredImage1.Dispose( ); throw new ApplicationException("Filters should not change image dimension."); } // convert 1st image to RGB if required if (filteredImage1.PixelFormat == PixelFormat.Format8bppIndexed) { GrayscaleToRGB coloringFilter = new GrayscaleToRGB( ); UnmanagedImage temp = coloringFilter.Apply(filteredImage1); filteredImage1.Dispose( ); filteredImage1 = temp; } UnmanagedImage filteredImage2 = null; // apply second filter, if it was specified if (filter2 != null) { filteredImage2 = filter2.Apply(sourceData); // check size of the result image if ((width != filteredImage2.Width) || (height != filteredImage2.Height)) { filteredImage1.Dispose( ); filteredImage2.Dispose( ); // we are not handling such situations yet throw new ApplicationException("Filters should not change image dimension."); } // convert 2nd image to RGB if required if (filteredImage2.PixelFormat == PixelFormat.Format8bppIndexed) { GrayscaleToRGB coloringFilter = new GrayscaleToRGB( ); UnmanagedImage temp = coloringFilter.Apply(filteredImage2); filteredImage2.Dispose( ); filteredImage2 = temp; } } // use source image as a second image, if second filter is not set if (filteredImage2 == null) { filteredImage2 = sourceData; } // do the job unsafe { byte *dst = (byte *)destinationData.ImageData.ToPointer( ); byte *src1 = (byte *)filteredImage1.ImageData.ToPointer( ); byte *src2 = (byte *)filteredImage2.ImageData.ToPointer( ); int dstOffset = destinationData.Stride - 3 * width; int src1Offset = filteredImage1.Stride - 3 * width; int src2Offset = filteredImage2.Stride - 3 * width; if (preserveLevel != 0.0) { // for each line for (int y = 0; y < height; y++) { // for each pixel for (int x = 0; x < width; x++) { double t1 = texture[y, x]; double t2 = 1 - t1; for (int i = 0; i < 3; i++, src1++, src2++, dst++) { *dst = (byte)Math.Min(255.0f, filterLevel * (t1 * (*src1) + t2 * (*src2)) + preserveLevel * (*src2)); } } src1 += src1Offset; src2 += src2Offset; dst += dstOffset; } } else { // for each line for (int y = 0; y < height; y++) { // for each pixel for (int x = 0; x < width; x++) { double t1 = texture[y, x]; double t2 = 1 - t1; for (int i = 0; i < 3; i++, src1++, src2++, dst++) { *dst = (byte)Math.Min(255.0f, t1 * *src1 + t2 * *src2); } } src1 += src1Offset; src2 += src2Offset; dst += dstOffset; } } } // dispose temp images filteredImage1.Dispose( ); if (filteredImage2 != sourceData) { filteredImage2.Dispose( ); } }