I can create an image of an arbitrary size using this code:
using var image = original.Clone(context =>
context.Pad(width, height, Color.White)
);
However, this places the original image in the center of the new image. Is there a way to specify the location (e.g., using AnchorPositionMode)? I'd like the original image in the bottom right corner of the new image.
Pad as described in the docs is designed for evenly padding an image to fit the new dimensions.
You can combine Resize with ResizOptions to position padding but if you require fine grained control use DrawImage.
Related
your help is much appreciated. I am using C# and EmguCV for image processing
I have tried noise removal, but nothing happens. I also tried image median filter, and it only works on the first image, but it does not work on the second image. It only makes the second image blurry and the objects larger and more square-like.
I want to remove obviously distinct objects(green ones) in my image below so that it would turn all black because they are obviously separated and are not grouped unlike the second image below.
Image 1:
At the same way, I want to do it in my image below, but remove only those objects -- (the black ones) -- that are not grouped/(lumped?) so that what remains on the image are the objects that are grouped/larger in scale?
Image 2:
Thank you
You may try Gaussian Blur and then apply Threshold to the image.
Gaussian Blur is a widely used effect in graphics software, typically to reduce image noise and reduce detail, which I think matches your requirements well.
For your 1st image:
CvInvoke.GaussianBlur(srcImg, destImg, new Size(0, 0), 5);//You may need to customize Size and Sigma depends on different input image.
You will get:
Then
CvInvoke.Threshold(srcImg, destImg, 10, 255, Emgu.CV.CvEnum.ThresholdType.Binary);
You will get:
For your 2nd image:
CvInvoke.GaussianBlur(srcImg, destImg, new Size(0, 0), 5);//You may need to customize Size and Sigma depends on different input image.
You will get:
Then
CvInvoke.Threshold(srcImg, destImg, 240, 255, Emgu.CV.CvEnum.ThresholdType.Binary);
You will get:
Hope this help!
You should first threshold the image using Otsus method. Second run connected component analysis on the threshold image. Third go over all the component that you found and for the ones that have a size that is smaller than some min size delete it from the original image.
cvThreshold (with CV_THRESH_BINARY/CV_THRESH_BINARY_INV(choose according to the image) + CV_THRESH_OTSU) http://www.emgu.com/wiki/files/1.3.0.0/html/9624cb8e-921e-12a0-3c21-7821f0deb402.htm + http://www.emgu.com/wiki/files/1.3.0.0/html/bc08707a-63f5-9c73-18f4-aeab7878d7a6.htm
CvInvoke.FindContours (RetrType == External,ChainApproxNone)
For each contour that we found in 2 calculate CvInvoke.ContourArea
If area is smaller than minArea draw on the original image(The one you want to filter) the value you want for them(0 I suppose) in the original image using CvInvoke.DrawContours with the current contour and with thickness==-1 to fill the inside of the contour.
I am using a zoomed picturebox. I want to retrieve the image Top-Left and Bottom-Right coordinates. But it is different from that of picturebox when the aspect ratio of the image doesn't match the picturebox. I wonder how I can get the image coordinates on the form.
Minus the Image size divided by 2 from the PictureBoxsize plus the Image size again.
This uses the Size.Subtract Method (Size, Size). MSDN
Size sizestep1 = Size.Subtract(new Size(PictureBox1.Image.Size.Width / 2, PictureBox1.Image.Size.Height / 2), PictureBox1.Size);
Size finalsize = Size.Add(sizestep1, PictureBox1.Image.Size);
// Convert to point.
Point BottomRightCoords = new Point(finalsize.Width, finalsize.Height);
And if you want to get the BottomRightCoords on the form, you have to add the PictureBox Location to it.
A little bit of mathematics suggested above + the code in the following link did the trick:
How to retrieve zoom factor of a WinForms PictureBox?
I'm able to fill a rectangle with an image and i apply a mask on top of the image using this code
args.DrawingSession.FillRectangle(rect, imgRnd, mask);
i need to apply some transform to this image, i'am able to do that with no issue, but i have encounter a strange issue, the last pixel is repeated.
i have used
imgRnd.ExtendX = CanvasEdgeBehavior.Wrap;
imgRnd.ExtendY = CanvasEdgeBehavior.Wrap;
and the image is repeated continuously.
My question is : there is a way to draw one time the image disabling and ExtendX and ExtendY?
FillRectangle will always fill all the pixels within the specified rectangle. The edge behavior enum controls what value they are filled with if the image is positioned such that it does not completely cover the rectangle being drawn.
How exactly are you transforming the image? Can you change that to also transform the rectangle itself, so you won't be trying to fill pixels that aren't covered by the image?
Another option is to use image effects (Microsoft.Graphics.Canvas.Effects namespace) which give much more detailed control than FillRectangle over how multiple images are transformed, combined, etc.
I am reading in a bitmap that is quite large and has a lot of useless space. The original image height is 2048 and the width is 1024.
I want to crop/clip the image for display purposes starting from the bottom left and showing an image height of 1047 and width of 1024 in c#. I've tried using CroppedBitmap but I keep getting an out of bounds error.
(The code below shows some random parameters as I started inputting a lot of stuff to get it to work even a little.)
This gives me the error:
CroppedBitmap cb = new CroppedBitmap((BitmapSource)bitmapImage,
new Int32Rect(2048,0,30,50));
EDIT: To put it another way, I want to get rid of the top half of the image.
CroppedBitmap cb = new CroppedBitmap(
bitmapImage,
new Int32Rect(0, (int)(bitmapImage.Height/2),
(int)bitmapImage.Width, (int)(bitmapImage.Height/2));
This will create a CroppedBitmap from the lower half of the bitmapImage. The Int32Rect should describe the part you want to keep.
I'm using the Drawstring method of the Graphics Class to Draw a Text on an Image.The Font is Specified before drawing.
G.DrawString(mytext, font, brush, 0, 0)
The Problem arises when the same text is drawn on an image with smaller size.The Text drawn appears to be larger.I'm looking for a solution to alter the font size according to the image size so that the text don't appear larger or smaller when drawn on images of different sizes.
I'm attaching the images with different sizes with the text of same font size drawn on it.
http://i.stack.imgur.com/ZShUI.jpg
http://i.stack.imgur.com/GUfbM.jpg
I can't directly post the image because I'm not allowed.
You would get most precise scaling by drawing on separate image and then slapping that image onto original one. You'd do that as follows:
Create in-memory Bitmap with enough space
Draw text on that bitmap in your default font
Draw image containing the text onto original image by scaling it to size you need
Code:
Bitmap textBmp = new Bitmap(100, 100);
Graphics textBmpG = Graphics.FromImage(textBmp);
textBmpG .DrawString("test 1", new Font(FontFamily.GenericSansSerif, 16), Brushes.Red, new PointF(0, 0));
Graphics origImgG = Graphics.FromImage(originalImg);
origImgG.DrawImage(textBmpG, new Rectangle(50, 50, 50, 50), new Rectangle(0, 0, 100, 100), GraphicsUnit.Pixel);
Take notice of last line and Rectangle parameters. Use them to scale your text bitmap onto original image. Alternatively, you can also choose Graphics.MeasureString method to determine how wide your text would be and make attempts until you get best one you can.
Use Graphics.MeasureString() to measure how big your string would be on the image
Decrease/increase font step by step accordingly
As you requested in comment I'll give you more detailed suggestion here. Say your original image width is WI1, and width of text on it using Graphics.MeasureString is WT1. If you resize your image to width WI2, then your perfect text width would be WT2 = WT1 * WI2 / WI1. Using DrawText method you may not be able to get this exact width because when you increase font by 1 it may jump over that value. So you have to make several attempts and find best. Pick a size of font, if resulting text width is smaller (measure with MeasureString), increase it until it becomes bigger than target and you've got about closest match. Same thing goes if it's too big. Decrease font step by step.
This is quick and dirty as you see, because you have many draws, but I can't think of better solution, unless you're using monospaced fonts.
Difference between those solutions would be that in first you can get text to fit EXACT size you need, but you probably would loose some font readability due to scaling. Second solution would give good readability, but you can't get pixel perfect size of text.
In my opinion you have two ways:
Draw text on original image and then resize resulting image (so, even text included in it)
Scale font size by a factor newImageWidth/originalImageWidth.
It's not perfect because you could have some problem with text height (if new image is not just scaled but with different aspect ratio), but it's an idea