EmguCV Mat change to LineSegment2D[] - c#

I'm using emguCV houghines Method and get a Mat Object, how can I get LineSegment2D[] by this Mat.
Sample of code:
Image<Bgr, Byte> img1 = new Image<Bgr, Byte>(fileName);
UMat uimage = new UMat();
CvInvoke.CvtColor(img1, uimage, ColorConversion.Bgr2Gray);
UMat mat = new UMat();
CvInvoke.HoughLines(uimage, mat, 1, Math.PI / 180, 20);
here I can see the size is not 0, how can I get these lines, or other function to show them

Related

Emgu Split Object

May I ask, how can I separate the detected object in a contour?
below is my source code
Image<Gray, byte> imgOutput = imgInput.Convert<Gray, byte>().ThresholdBinary(new Gray(100), new Gray(255)); Emgu.CV.Util.VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint(); Mat m = new Mat();
//Image<Gray, byte> imgOut = new Image<Gray, byte>(imgInput.Width, imgInput.Height, new Gray(0));
CvInvoke.FindContours(imgOutput, contours, m, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);
if (contours.Size > 0)
{
double perimeter = CvInvoke.ArcLength(contours[1], true);
VectorOfPoint approx = new VectorOfPoint();
CvInvoke.ApproxPolyDP(contours[1], approx, 0.04 * perimeter, true);
CvInvoke.DrawContours(imgInput, contours, 1, new MCvScalar(0, 0, 255), 2);
pictureBox2.Image = imgInput.Bitmap;
}
Separated objects result.

Face Rotation direction detection using c# and emgucv

I am new to Emgucv and I am working on face movement direction detection
I had come across many codes in Internet but they are very difficult to understand.
So can you please provide a easy and understandable code or links for learning this situation.
Thanks in advance
Based on this :
Bitmap bmp = new Bitmap(); // your bitmap contain a face
Mat mat = GetMatFromSDImage(bmp);
using (var nextFrame = mat.ToImage<Bgr, Byte>())
{
if (nextFrame != null)
{
Image<Gray, byte> grayframe = nextFrame.Convert<Gray, byte>();
Rectangle[] faces = mHaarCascade.DetectMultiScale(grayframe, 1.1, 10, Size.Empty);
if (faces.Count() > 0)
{
// some faces are detected
// you can check the X and Y of faces here
}
}
}
private Mat GetMatFromSDImage(Bitmap image)
{
int stride = 0;
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, image.Width, image.Height);
System.Drawing.Imaging.BitmapData bmpData = image.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, image.PixelFormat);
System.Drawing.Imaging.PixelFormat pf = image.PixelFormat;
if (pf == System.Drawing.Imaging.PixelFormat.Format32bppArgb)
{
stride = image.Width * 4;
}
else
{
stride = image.Width * 3;
}
Image<Bgra, byte> cvImage = new Image<Bgra, byte>(image.Width, image.Height, stride, (IntPtr)bmpData.Scan0);
image.UnlockBits(bmpData);
return cvImage.Mat;
}
so faces contains the array of Rectangle bounding faces. you can check the X and Y property of the rectangles to check if it moves and compares it with the initial position to detect it's direction.
Update based on comment
To detect head rotation a simple solution can be eye detection. you can use haarcascade_eye.xml to detect ayes. then you can calculate the rotation form each eye's X and Y position.
Here you can find a simple example of eye detection

RenderTargetBitmap doesn't seem to render my rectangle

I have the following code:
LinearGradientBrush linGrBrush = new LinearGradientBrush();
linGrBrush.StartPoint = new Point(0,0);
linGrBrush.EndPoint = new Point(1, 0);
linGrBrush.GradientStops.Add(new GradientStop(Colors.Red, 0.0));
linGrBrush.GradientStops.Add(new GradientStop(Colors.Yellow, 0.5));
linGrBrush.GradientStops.Add(new GradientStop(Colors.White, 1.0));
Rectangle rect = new Rectangle();
rect.Width = 1000;
rect.Height = 1;
rect.Fill = linGrBrush;
rect.Arrange(new Rect(0, 0, 1, 1000));
rect.Measure(new Size(1000, 1));
If I do
myGrid.Children.Add(rect);
Then the gradient is drawn fine on the window.
I want to use this gradient for an intensity map somewhere else, so I need to get the pixels out of it. To do this, I understand I can convert it to a bitmap, using RenderTargetBitmap. Here's the next part of the code:
RenderTargetBitmap bmp = new RenderTargetBitmap(
1000,1,72,72,
PixelFormats.Pbgra32);
bmp.Render(rect);
Image myImage = new Image();
myImage.Source = bmp;
To test this, I do:
myGrid.Children.Add(myImage);
But nothing appears on the window. What am I doing wrong?
Arrange has to be called after Measure, and the Rect values should be passed correctly.
Instead of
rect.Arrange(new Rect(0, 0, 1, 1000)); // wrong width and height
rect.Measure(new Size(1000, 1));
you should do
var rect = new Rectangle { Fill = linGrBrush };
var size = new Size(1000, 1);
rect.Measure(size);
rect.Arrange(new Rect(size));
var bmp = new RenderTargetBitmap(1000, 1, 96, 96, PixelFormats.Pbgra32);
bmp.Render(rect);

EmguCV snake function

I am trying to use snake active contour from EmguCV ,but i don't take anything.Here is my code:
Image<Gray, Byte> img = new Image<Gray, Byte>(300, 300, new Gray());
Point center = new Point(100, 100);
double width = 20;
double height = 40;
Rectangle rect = new Rectangle(center, new Size(20, 20));
img.Draw(rect, new Gray(255.0), -1);
using (MemStorage stor = new MemStorage())
{
Seq<Point> pts = new Seq<Point>((int)SEQ_TYPE.CV_SEQ_POLYGON, stor);
pts.Push(new Point(20, 20));
pts.Push(new Point(20, 280));
pts.Push(new Point(280, 280));
pts.Push(new Point(280, 20));
//Image<Gray, Byte> canny = img.Canny(100.0, 40.0);
Seq<Point> snake = img.Snake(pts, 0.1f, 0.5f, 0.4f, new Size(21, 21), new MCvTermCriteria(500, 0.1), stor);
img.Draw(pts, new Gray(120), 1);
img.Draw(snake, new Gray(80), 2);
What i am doing wrong?Any idea?
you miss to draw your initialization points.
I have setup some code for you and for the whole community as there are no emgu snakes sample out there.
private void TestSnake()
{
Image<Gray, Byte> grayImg = new Image<Gray, Byte>(400, 400, new Gray());
Image<Bgr, Byte> img = new Image<Bgr, Byte>(400, 400, new Bgr(255,255,255));
// draw an outer circle on gray image
grayImg.Draw(new Ellipse(new PointF(200,200),new SizeF(100,100),0), new Gray(255.0), -1);
// inner circle on gray image to create a donut shape :-)
grayImg.Draw(new Ellipse(new PointF(200, 200), new SizeF(50, 50), 0), new Gray(0), -1);
// this is the center point we'll use to initialize our contour points
Point center = new Point(200, 200);
// radius of polar points
double radius = 70;
using (MemStorage stor = new MemStorage())
{
Seq<Point> pts = new Seq<Point>((int)Emgu.CV.CvEnum.SEQ_TYPE.CV_SEQ_POLYGON, stor);
int numPoint = 100;
for (int i = 0; i < numPoint; i++)
{ // let's have some fun with polar coordinates
Point pt = new Point((int)(center.X + (radius * Math.Cos(2 * Math.PI * i / numPoint))), (int)(center.Y + (radius * Math.Sin(2 * Math.PI * i / numPoint))) );
pts.Push(pt);
}
// draw contour points on result image
img.Draw(pts, new Bgr(Color.Green), 2);
// compute snakes
Seq<Point> snake = grayImg.Snake(pts, 1.0f, 1.0f, 1.0f, new Size(21, 21), new MCvTermCriteria(100, 0.0002), stor);
// draw snake result
img.Draw(snake, new Bgr(Color.Yellow), 2);
// use for display in a winform sample
imageBox1.Image = grayImg;
imageBox2.Image = img;
}
}
Hope this helps, just change some params and you will be surprised of result.

How can I draw a circle with antialiasing and gaussian line intensity using EmguCV (OpenCV)?

I need to draw the most perfect circle possible. EmguCV seems to lack an anti-aliasing option.
I'm trying to use SmoothGaussian, but the circle still does not look good/smooth enough.
Also, the circle line intensity should have Gaussian shape (i.e.: brighter in the center).
How can I achieve that?
Here is what I'm doing now:
using (Image<Gray, Byte> img = new Image<Gray, byte>(800, 800, new Gray(0)))
{
PointF center = new PointF(img.Width / 2, img.Height / 2);
//Center line
float r = 200.0f;
CircleF circle = new CircleF(center, r);
img.Draw(circle, new Gray(255), 1);
img._SmoothGaussian(7, 7, 3, 3);
}
If you use Brg, Brga or Gray color you can use that hack:
using(var graph = Graphics.FromImage(image.Bitmap))
{
graph.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
graph.DrawEllipse(new Pen(color.BackColor), x, y, d`i`ameter, diameter);
}
`
Edit:
You can also use cvInvoke
var center = new Point(x, y);
var color = new Bgr(this.color.BackColor);
CvInvoke.cvCircle(image.Ptr, center, radius, color.MCvScalar, thickness, Emgu.CV.CvEnum.LINE_TYPE.CV_AA, 0);
`

Categories

Resources