I am trying to create this 2D polygon but I get a blank a image after plotting the points.
The Point class takes x and y axes as parameters. Point(x, y)
`
Bitmap bitmap = new Bitmap(1000, 800, PixelFormat.Format32bppPArgb);
Graphics graphics = Graphics.FromImage(bitmap);
Pen pen = new Pen(System.Drawing.Color.Blue, 2);
Point[] points =
{
new Point(2408, 919),
new Point(2596, 919),
new Point(2596, 1200),
new Point(2408, 919),
new Point(2596, 1505),
new Point(2572, 1505),
new Point(2408, 1200),
new Point(2408, 919)
};
graphics.DrawPolygon(pen, points);
bitmap.Save("DrawPolygon.png");
Update: The polygon now displays as per Jimi's first comment. New issue is the polygon shortest length always sit on the horizontal axis and the polygon lines are crossing.
Related
I want to draw a rotated rectangle. The canny image is not one counter it is a set of counters. So I want to get all points of all counters. e.g.
Points[] pts = points of all counters.
Please see attached image.
The canny show all edges in your image, not an external contour. This one way (but not the only one) to do object detection (foreground / background extraction).
The following snippet extract object roi (Min area rect) by using a canny edge detector. Be carrefull about canny thresh parameteres comming from otsu threshold.
Hope it helps.
Detection result
Image<Gray,byte> imageFullSize = new Image<Gray, byte>(imagePath);
Rectangle roi = new Rectangle(Your Top Left X,Your Top Left Y,Your ROI Width,Your ROI Height);
//Now get a roi (No copy, it is a new header pointing original image
Image<Gray,byte> image = imageFullSize.GetSubRect(roi);
//Step 1 : contour detection using canny
//Gaussian noise removal, eliminate background false détections
image._SmoothGaussian(15);
//Canny thresh based on otsu threshold value:
Mat binary = new Mat();
double otsuThresh = CvInvoke.Threshold(image, binary, 0, 255, ThresholdType.Binary | ThresholdType.Otsu);
double highThresh = otsuThresh;
double lowThresh = otsuThresh * 0.5;
var cannyImage = image.Canny(lowThresh, highThresh);
//Step 2 : contour extraction
Mat hierarchy=new Mat();
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
CvInvoke.FindContours(cannyImage,contours,hierarchy,RetrType.External,ChainApproxMethod.ChainApproxSimple);
//Step 3 : contour fusion
List<Point> points=new List<Point>();
for(int i = 0; i < contours.Size; i++)
{
points.AddRange(contours[i].ToArray());
}
//Step 4 : Rotated rect
RotatedRect minAreaRect = CvInvoke.MinAreaRect(points.Select(pt=>new PointF(pt.X,pt.Y)).ToArray());
Point[] vertices = minAreaRect.GetVertices().Select(pt => new Point((int)pt.X, (int)pt.Y)).ToArray();
//Step 5 : draw result
Image <Bgr,byte > colorImageFullSize =new Image<Bgr, byte>(imagePath);
Image <Bgr,byte > colorImage =colorImageFullSize.GetSubRect(roi);
colorImage.Draw(vertices,new Bgr(Color.Red),2 );
I am trying to detect Circle inside Rectangle in AForge. I have successfully determined Rectangles but unable to find circles inside Rectangle. How to find shape inside another shape in AForge.
string strPath = Server.MapPath("~/Recipt001.png");
Bitmap myBitmap = new Bitmap(strPath);
//Some filters Grayscale, invert, threshold
//Blod Filtering
BlobCounter blobCounter = new BlobCounter();
blobCounter.ProcessImage(temp);
blobCounter.ObjectsOrder = ObjectsOrder.YX;
blobCounter.FilterBlobs = true;
Blob[] blobs = blobCounter.GetObjectsInformation();
Graphics g = Graphics.FromImage(myBitmap);
Pen redPen = new Pen(Color.Red, 2);
SimpleShapeChecker shapeChecker = new SimpleShapeChecker();
// dictionary of color to highlight different shapes
Dictionary<PolygonSubType, Color> colors = new Dictionary<PolygonSubType, Color>();
colors.Add(PolygonSubType.Unknown, Color.White);
colors.Add(PolygonSubType.Trapezoid, Color.Orange);
colors.Add(PolygonSubType.Parallelogram, Color.Red);
colors.Add(PolygonSubType.Rectangle, Color.Green);
colors.Add(PolygonSubType.Square, Color.Blue);
colors.Add(PolygonSubType.Rhombus, Color.Gray);
colors.Add(PolygonSubType.EquilateralTriangle, Color.Pink);
colors.Add(PolygonSubType.IsoscelesTriangle, Color.Purple);
colors.Add(PolygonSubType.RectangledTriangle, Color.SkyBlue);
colors.Add(PolygonSubType.RectangledIsoscelesTriangle, Color.SeaGreen);
for (int i = 0, n = blobs.Length; i < n; i++)
{
List<IntPoint> corners;
List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]);
Point center;
double radius;
if (shapeChecker.IsQuadrilateral(edgePoints, out corners))
{
if (shapeChecker.CheckPolygonSubType(corners) == PolygonSubType.Rectangle)
{
g.DrawPolygon(redPen, ToPointsArray(corners));
}
}
}
redPen.Dispose();
g.Dispose();
None of image processing libraries and even image processing in MATLAB lets you search ROI inside ROI (ROI - region of intrest like rectangles or circles). Concept is CROP REGION -> SEARCH OBJECTS IN REGION
So first locate primary rectangles, thereafter crop image to rectangles and perform circle search inside them. Otherwise search for all circles and all rectangles and then classify circles to be belonging to which rectangle using simple maths.
I have 4 float points (positions in 2D) and I want to draw and fill a polygon (with vertices at those 4 positions) in 2D.
How can I do that with sharpdx?
I have found how to draw and fill a polygon. I have used drawGeometry and fillGeometry methods of RenderTarget object.
I wont mention how to initialize the directx
PathGeometry geo1;
GeometrySink sink1;
FactoryD2D factory = new FactoryD2D();
var dpi = factory.DesktopDpi;
RenderTarget renderTarget;
renderTarget = new RenderTarget(factory, backBuffer, new RenderTargetProperties()
{
DpiX = dpi.Width,
DpiY = dpi.Height,
MinLevel = SharpDX.Direct2D1.FeatureLevel.Level_DEFAULT,
PixelFormat = new SharpDX.Direct2D1.PixelFormat(Format.Unknown, AlphaMode.Ignore),
Type = RenderTargetType.Hardware,
Usage = RenderTargetUsage.None
});
// and after all initialization
pta[0] = new SharpDX.Vector2(pts[4].X, pts[4].Y);
pta[1] = new SharpDX.Vector2(pts[5].X, pts[5].Y);
pta[2] = new SharpDX.Vector2(pts[6].X, pts[6].Y);
pta[3] = new SharpDX.Vector2(pts[7].X, pts[7].Y);
geo1 = new PathGeometry(factory);
sink1 = geo1.Open();
sink1.BeginFigure(pta[0], new FigureBegin());
sink1.AddLines(new SharpDX.Vector2[] { pta[1], pta[2], pta[3] });
sink1.EndFigure(new FigureEnd());
sink1.Close();
Color penColor = Color.Black;
SolidColorBrush penBrush = new SolidColorBrush(g, new SharpDX.Color(penColor.R, penColor.G, penColor.B));
Color color = AddColor(pt, zmin, zmax);
SolidColorBrush aBrush = new SolidColorBrush(g, new SharpDX.Color(color.R, color.G, color.B));
renderTarget.DrawGeometry(geo1, penBrush);
renderTarget.FillGeometry(geo1, aBrush);
geo1.Dispose();
sink1.Dispose();
You can add other geos and sinks in order to add more shapes on to it
Hope this help to somebody who is lost and trying to find an answer desperately like me
I am using croppic to crop images. Is there any possibility to extend its functionality to rotate the image, before sending it to crop. Something like this
var angle = 0;
$('#button').on('click', function() {
angle += 90;
$("#image").rotate(angle);
});
Here is the demo
I can manage to to rotate the image, but the cropped image is not in rotated position. Any idea?
Update:
Now the image is getting rotated. I have managed to keep rotated image by the same handler that uses crop method. But the cropped image in rotated position occurs only when the rotated image is in 180 rotation. When its in the 90/270, the image, obviously don't fit in the bounding box (if you have seen croppic) and I get a MemoryOutOfBound exception.
Here is the code:
public static Bitmap RotateImage(Bitmap bmpSrc, float theta)
{
Matrix mRotate = new Matrix();
mRotate.Translate(bmpSrc.Width / -2, bmpSrc.Height / -2, MatrixOrder.Append);
mRotate.RotateAt(theta, new System.Drawing.Point(0, 0), MatrixOrder.Append);
using (GraphicsPath gp = new GraphicsPath())
{ // transform image points by rotation matrix
gp.AddPolygon(new System.Drawing.Point[] { new System.Drawing.Point(0, 0), new System.Drawing.Point(bmpSrc.Width, 0), new System.Drawing.Point(0, bmpSrc.Height) });
gp.Transform(mRotate);
System.Drawing.PointF[] pts = gp.PathPoints;
// create destination bitmap sized to contain rotated source image
Rectangle bbox = boundingBox(bmpSrc, mRotate);
Bitmap bmpDest = new Bitmap(bbox.Width, bbox.Height);
using (Graphics gDest = Graphics.FromImage(bmpDest))
{ // draw source into dest
Matrix mDest = new Matrix();
mDest.Translate(bmpDest.Width / 2, bmpDest.Height / 2, MatrixOrder.Append);
gDest.Transform = mDest;
gDest.DrawImage(bmpSrc, pts);
return bmpDest;
}
}
}
private static Rectangle boundingBox(Image img, Matrix matrix)
{
GraphicsUnit gu = new GraphicsUnit();
Rectangle rImg = Rectangle.Round(img.GetBounds(ref gu));
// Transform the four points of the image, to get the resized bounding box.
System.Drawing.Point topLeft = new System.Drawing.Point(rImg.Left, rImg.Top);
System.Drawing.Point topRight = new System.Drawing.Point(rImg.Right, rImg.Top);
System.Drawing.Point bottomRight = new System.Drawing.Point(rImg.Right, rImg.Bottom);
System.Drawing.Point bottomLeft = new System.Drawing.Point(rImg.Left, rImg.Bottom);
System.Drawing.Point[] points = new System.Drawing.Point[] { topLeft, topRight, bottomRight, bottomLeft };
GraphicsPath gp = new GraphicsPath(points,new byte[] { (byte)PathPointType.Start,
(byte)PathPointType.Line, (byte)PathPointType.Line,
(byte)PathPointType.Line });
gp.Transform(matrix);
return Rectangle.Round(gp.GetBounds());
}
I think main issue is in the bounding box.
using (Bitmap rotate = new Bitmap(RotateImage(bmp, rotateAngle)))
{
using (Bitmap cloneRotate = (Bitmap)rotate.Clone()) //getting error here
{
//some stuffs
cloneRotate.save(mycroppedimageurl);
}
}
I'm using a single sprite sheet image as the main texture for my breakout game. The image is this:
My code is a little confusing, since I'm creating two elements from the same Texture using a Point, to represent the element size and its position on the sheet, a Vector, to represent its position on the viewport and a Rectangle that represents the element itself.
Texture2D sheet;
Point paddleSize = new Point(112, 24);
Point paddleSheetPosition = new Point(0, 240);
Vector2 paddleViewportPosition;
Rectangle paddleRectangle;
Point ballSize = new Point(24, 24);
Point ballSheetPosition = new Point(160, 240);
Vector2 ballViewportPosition;
Rectangle ballRectangle;
Vector2 ballVelocity;
My initialization is a little confusing as well, but it works as expected:
paddleViewportPosition = new Vector2((GraphicsDevice.Viewport.Bounds.Width - paddleSize.X) / 2, GraphicsDevice.Viewport.Bounds.Height - (paddleSize.Y * 2));
paddleRectangle = new Rectangle(paddleSheetPosition.X, paddleSheetPosition.Y, paddleSize.X, paddleSize.Y);
Random random = new Random();
ballViewportPosition = new Vector2(random.Next(GraphicsDevice.Viewport.Bounds.Width), random.Next(GraphicsDevice.Viewport.Bounds.Top, GraphicsDevice.Viewport.Bounds.Height / 2));
ballRectangle = new Rectangle(ballSheetPosition.X, ballSheetPosition.Y, ballSize.X, ballSize.Y);
ballVelocity = new Vector2(3f, 3f);
And the drawing:
spriteBatch.Draw(sheet, paddleViewportPosition, paddleRectangle, Color.White);
spriteBatch.Draw(sheet, ballViewportPosition, ballRectangle, Color.White);
The problem is I can't detect the collision properly, using this code:
if(ballRectangle.Intersects(paddleRectangle))
{
ballVelocity.Y = -ballVelocity.Y;
}
What am I doing wrong?
You're testing collision based on sourceRectangles for the sprite sheet texture. Those rectangles (paddleRectangle, ballRectangle) are defined in terms of texture coordinates - that is where those sprites are on the sheet. It makes no sense to test those rectangles for collision.
You need to use screen coordinates for collision, that is, you need different rectangles defined with screen positions:
Rectangle paddleViewportRectangle = new Rectangle(paddleViewportPosition.X,
paddleViewportPosition.Y,
paddleSize.X,
paddleSize.Y);
Rectangle ballViewportRectangle = new Rectangle(ballViewportPosition.X,
ballViewportPosition.Y,
ballSize.X,
ballSize.Y);
if(ballViewportRectangle.Intersects(paddleViewportRectangle))
{
ballVelocity.Y = -ballVelocity.Y;
}