Emgucv drawn items - c#

I am making a project using Emgucv library, he problem is as follows,
I Capture image
detect feature
extract it
draw it
After that i copy the drawn items in a blank image, now I want find contours inside that new image, but the result is always bull, Why is That?
Thanks in advance

Additional information would be good.
But for you to be able to find the contours, the new image must be converted into a binary image like the ff: (assuming newImage is of type Image)
Image<Gray,byte> binaryImage = newImage.ThresholdBinary(new Gray(1), new Gray(255));
To detect contours and write to resultImage:
for (var contour = binaryImage.FindContours(
CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
RETR_TYPE.CV_RETR_CCOMP);
contour != null;
contour = contour.HNext)
{
resultImage.Draw(contour, new Gray(255), -1);
}

Related

Bitmap object needed in MAUI.NET?

I need to store a bitmap object in my MAUI.NET application.
To be clear - in my definition: bitmap is a representation of the image by the 2 dimensional array of pixels, that have at least R,G and B value.
In .NET 4.7 it wasn't already such an object, but there was a NuGet System.Drawings.Common that allowed me to use such an object.
How to handle such a situation in MAUI.NET?
edit:
Sorry if I wasn't clear. This is my scenario:
I am not about drawing and image in UI.
I want to let user specify path to file and then I need to have a Bitmap of this picture/image, because I need to pass it to different layers/project -> pass it to algorithms with the logic that would process it.
So this would be a code I would do in .NET Framework 4...:
string filepath = someFileSystemDialog.Result;
Bitmap bitmap = new Bitmap(filepath); // here is the problem, in previous .NET there was Bitmap object wchich was perfect, here is lack
Bitmap processedBitmap = MyOtherProjectWithLogicAlgorithms.ProcessAnImage(bitmap);
processedBitmap.Save(finalOutputPath, ImageFormat.Png);
But in Maui.NET from a filedialog I managed to get something like below:
var fileResult = await FilePicker.Default.PickAsync(...);
if(fileResult != null)
{
ImageSource is = ImageSource.FromFile(fileResult.FullPath);
Bitmap bm = ??(is); // how to get Bitmap from an ImageSource ?
MyOtherProjectWithLogicAlgorithms is an other .NET project that (for compatibility would also have .NET 6.0) - I guess this is required to work with MAUI.NET as dependency project.
There is Bitmap but seems that is dedicated only to Android:
Android.Graphics.Bitmap - Can I use it in general code for all the platforms?
edit:
The solution is SkiaSharp. Look into comments below for an alternative.
If I understand your means correctly, you can paint graphical objects in the Microsoft.Maui.Graphics namespace .
First,Images can be drawn on an ICanvas using the DrawImage method, which requires an IImage argument, and x, y, width, and height arguments, of type float.
The following example shows how to load an image and draw it to the canvas:
using Microsoft.Maui.Graphics.Platform;
...
IImage image;
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
{
image = PlatformImage.FromStream(stream);
}
if (image != null)
{
canvas.DrawImage(image, 10, 10, image.Width, image.Height);
}
For more information, you can check: Draw an image .
Second, you can also paint an image.The ImagePaint class, that's derived from the Paint class, is used to paint a graphical object with an image.
The ImagePaint class defines an Image property, of type IImage, which represents the image to paint. The class also has an IsTransparent property that returns false.
To paint an object with an image, load the image and assign it to the Image property of the ImagePaint object.
The following example shows how to load an image and fill a rectangle with it:
using Microsoft.Maui.Graphics.Platform;
...
IImage image;
var assembly = GetType().GetTypeInfo().Assembly;
using (var stream = assembly.GetManifestResourceStream("GraphicsViewDemos.Resources.Images.dotnet_bot.png"))
{
image = PlatformImage.FromStream(stream);
}
if (image != null)
{
ImagePaint imagePaint = new ImagePaint
{
Image = image.Downsize(100)
};
canvas.SetFillPaint(imagePaint, RectF.Zero);
canvas.FillRectangle(0, 0, 240, 300);
}
For more details, you can check: Paint graphical objects

how to crop image with polygon in c#

I'm making a labeling tool.
Goal :By drawing a polygon on the picture, you have to export the image ​​inside the polygon to the outside.
example
extract
This is what I drew in the my program.
But I don't know how to extract this region. I want to know how to extract this area.
I have saved the vertices of the picture above in an object. But I don't know how to extract data from the image through these vertices
========================================
So I found this.
https://www.codeproject.com/Articles/703519/Cropping-Particular-Region-In-Image-Using-Csharp
but it is not work
Can't convert Bitmap to IplImage
It doesn't work for the same reason.
In the post, I am going to use opencvsharp 4.x, but the program I am fixing now is .netframework 3.5, so it does not support opencvsharp 4.x.
What should I do?
============================
I made a function referring to the answer, but it doesn't work...
I want to know why.
void CropImage(Bitmap bitmap, Point[] points)
{
Rectangle rect = PaddingImage(points, bitmap);
TextureBrush textureBrush = new TextureBrush(bitmap);
Bitmap bmp1 = new Bitmap(rect.Width, rect.Height);
using (Graphics g = Graphics.FromImage(bmp1))
{
g.FillPolygon(textureBrush, points);
}
string ima_path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
bmp1.Save(ima_path + "\\Image.png", ImageFormat.Png);
}
extract Image
original
If you use a small polygon, there is no output at all.
You will notice that the two images are slightly different.
It seems to me that the part where the center point is cut and extracted is different. I don't know if what I was thinking is correct.
You would create a new bitmap, at least as large as the bounding box of your polygon. Create a graphics object from this new bitmap. You can then draw the polygon to this bitmap, using the original image as a texture brush. Note that you might need to apply transform matrix to translate from the full image coordinates to the cropped image coordinates.
Note that it looks like you have radiological images. These are typically 16 bit images, so they will need to be converted to 8bit mono, or 24bit RGB before they can be used. This should already be done in the drawing code if you have access to the source. Or you can do it yourself.
this works for me
private Bitmap CropImage(Bitmap bitmap, List<Point> points)
{
int pminx = 9999, pminy = 9999, pmaxx = 0, pmaxy = 0; System.Drawing.Point[] pcol = new System.Drawing.Point[points.Count]; int i = 0;
foreach (Point pc in points)
{
if (pc.X > pmaxx) pmaxx = (int)pc.X;
if (pc.Y > pmaxy) pmaxy = (int)pc.Y;
if (pc.X < pminx) pminx = (int)pc.X;
if (pc.Y < pminy) pminy = (int)pc.Y;
pcol[i] = new System.Drawing.Point((int)pc.X, (int)pc.Y);
i++;
}
TextureBrush textureBrush = new TextureBrush(bitmap);
Bitmap bmpWrk = new Bitmap(bitmap.Width, bitmap.Height);
using (Graphics g = Graphics.FromImage(bmpWrk))
{
g.FillPolygon(textureBrush, pcol);
}
System.Drawing.Rectangle CropRect = new System.Drawing.Rectangle(pminx, pminy, pmaxx - pminx, pmaxy - pminy);
return bmpWrk.Clone(CropRect, bmpWrk.PixelFormat);
}

Xamarin.iOS Image on Image Watermark

How can I add a png image as a watermark to a larger image using Xamarin.iOS c# and save the output to the device?
I figured out the Xamarin.Android version from another question posted here.
Thanks in Advance!!
Using an image context, you can draw the original, then the watermark at the necessary location and obtain a new image from the context.
ImageContext example:
var originalImage = UIImage.FromBundle("buymore.jpg");
var watermarkImage = UIImage.FromFile("vs.png");
UIGraphics.BeginImageContextWithOptions(originalImage.Size, true, 1.0f);
originalImage.Draw(CGPoint.Empty);
watermarkImage.Draw(new CGRect(new CGPoint(200, 200), watermarkImage.Size));
var processedImage = UIGraphics.GetImageFromCurrentImageContext();
If your original and watermark images are the same size, you can use a CIFilter (CISourceOverCompositing) to "overlay" one image on top of another (assuming your watermark has a white or alpha background. This is my preferred method due to the speed.
CISourceOverCompositing example:
UIImage processedimage;
using (var filter = new CISourceOverCompositing())
{
filter.Image = new CIImage(UIImage.FromBundle("vs.png"));
filter.BackgroundImage = new CIImage(UIImage.FromBundle("buymore.jpg"));
processedimage = UIImage.FromImage(filter.OutputImage);
}

Fillholes function in Aforge

I need to use Fillholes function of Aforge, it accepts binary image. I manipulated all pixels to black or white pixels using following code in c#:
bitmapimage.SetPixel(i, j, Color.FromArgb(255,255,255)); // for white pixel
bitmapimage.SetPixel(i, j, Color.FromArgb(0,0,0)); // for black pixel
But when I apply fillholes function to bitmap image, I get this exception:
"Source pixel format is not supported by the filter"
Kindly anyone help why I am getting this exception ... is bitmap image not converted to Binary by all using setpixel?
Just changing the pixel colors will not change the pixel format of your image.
You first need to make sure that you have a gray scale image using some gray scale filter, then make sure that the gray scale image is binary through some threshold filter. Once the image has been pre-processed using these steps, you may apply the FillHoles filter.
AForge.NET offers helper classes to merge several filters, so you can combine all three filters into one total filter using the FiltersSequence class.
Assuming that your original Bitmap image is named bitmap, you can then apply the fill holes filter for example like this:
var filter = new FiltersSequence(Grayscale.CommonAlgorithms.BT709,
new Threshold(100), new FillHoles());
var newBitmap = filter.Apply(bitmap);
AForge FillHoles Class
The filter allows to fill black holes in white object in a binary image. It is possible to specify maximum holes' size to fill using MaxHoleWidth and MaxHoleHeight properties.
The filter accepts binary image only, which are represented as 8 bpp images.
Sample usage:
C#
// create and configure the filter
FillHoles filter = new FillHoles( );
filter.MaxHoleHeight = 20;
filter.MaxHoleWidth = 20;
filter.CoupledSizeFiltering = false;
// apply the filter
Bitmap result = filter.Apply( image );
The above was found at http://www.aforgenet.com/framework/docs/html/68bd57bd-1fd6-6c4e-4500-ed4726bc836e.htm
You have to convert your bitmapImage to a binary image represented as an 8 bpp image. Here is one way to do it.
UnmanagedImage grayImage = null;
if (image.PixelFormat == PixelFormat.Format8bppIndexed)
{
grayImage = bitmapImage;
}
else
{
grayImage = UnmanagedImage.Create(image.Width, image.Height, PixelFormat.Format8bppIndexed);
}

Barcode i25 using ItextSharp

i am using BarcodeInter25 class to make barcode. I am able to make it but its just blur how can it become more sharp ??
also its background white colour is not completely white
My Code:
BarcodeInter25 code25 = new BarcodeInter25();
Rectangle r = new iTextSharp.text.Rectangle(38, 152);
code25.ChecksumText = false;
code25.Code = "some digits";
code25.BarHeight = 2
System.Drawing.Image i = code25.CreateDrawingImage(System.Drawing.Color.Black, System.Drawing.Color.White);
MemoryStream ms = new MemoryStream();
i.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
Image img = Image.GetInstance(ms.ToArray());
ms.Dispose();
Looking at your code, it should be obvious why the barcode is blurry. You convert it to a System.Drawing.Image (making it a raster image) and then you convert it to an iTextSharp.text.Image (but by then the image is already blurry).
The correct way to achieve what you want, is to create an iTextSharp.text.Image straight from the barcode (do not pass through System.Drawing.Image). This can be done like this:
BarcodeInter25 code25 = new BarcodeInter25();
Rectangle r = new iTextSharp.text.Rectangle(38, 152);
code25.ChecksumText = false;
code25.Code = "some digits";
code25.BarHeight = 2;
PdfContentByte cb = writer.DirectContent;
Image img = code25.CreateImageWithBarcode(cb, null, null);
Now the Image object won't be a raster image (with pixels that make the lines blurry), but it will be a true vector image (no pixels, but instructions such as moveTo(), lineTo() and stroke()). Vector data has the advantage that it is resolution independent: you can zoom in and zoom out as much as you want, it will always be sharp.
This is explained in Chapter 10 of my book where you'll find the Barcodes example. In that chapter, you'll also discover the setFont() (or in iTextSharp the Font property). I quote from the API documentation:
public void setFont(BaseFont font)
Sets the text font.
Parameters:
font - the text font. Set to null to suppress any text
So if you don't want to see any text, you can add the following line to the above code snippet:
code25.Font = null;
You should avoid re-sizing by any means. The output is most likely pixel-perfect but when you scale it up/down a bilinear filter will smooth it rendering it blurry.
I had the same exact problem by embedding a QRC code in a PDF and solved it by avoiding a resize.
If you really need a different size apply it programmatically in code by using the correct interpolation algorithm.

Categories