I am using Emgu CV's SURF and I used int j = CvInvoke.cvCountNonZero(mask); to find matched pair points.
The problem how to return this value into main()?
...
...
...
public static Image<Bgr, Byte> Draw(Image<Gray, Byte> modelImage, Image<Gray, byte> observedImage, out long matchTime)
{
HomographyMatrix homography;
VectorOfKeyPoint modelKeyPoints;
VectorOfKeyPoint observedKeyPoints;
Matrix<int> indices;
Matrix<byte> mask;
FindMatch(modelImage, observedImage, out matchTime, out modelKeyPoints, out observedKeyPoints, out indices, out mask, out homography);
//Draw the matched keypoints
Image<Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT);
int j = CvInvoke.cvCountNonZero(mask);
return result;
}
You can create a simple result object:
public class DrawingResult {
public Image<Bgr, Byte> Images { get; private set; }
public int Count {get; private set; }
public DrawingResult(Image<Bgr, Byte> images, int count) {
Images = images;
Count = count;
}
}
And in your method:
public static DrawingResult Draw(Image<Gray, Byte> modelImage, Image<Gray, byte> observedImage, out long matchTime)
{
HomographyMatrix homography;
VectorOfKeyPoint modelKeyPoints;
VectorOfKeyPoint observedKeyPoints;
Matrix<int> indices;
Matrix<byte> mask;
FindMatch(modelImage, observedImage, out matchTime, out modelKeyPoints, out observedKeyPoints, out indices, out mask, out homography);
//Draw the matched keypoints
Image<Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints,
indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT);
int j = CvInvoke.cvCountNonZero(mask);
return new DrawingResult(result, j);
}
And in the main method:
DrawingResult result = MyClass.Draw(...);
int count = result.Count;
Image<Bgr, Byte> images = result.Images;
Related
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.
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
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
i need to implement Skeletonization in Emgu CV but i not have success.
I have a code mentioned on the website below but it does not work :
Skeletonization using EmguCV^]
This code below DONT work:
Image<Gray, Byte> eroded = new Image<Gray, byte>(img2.Size);
Image<Gray, Byte> temp = new Image<Gray, byte>(img2.Size);
Image<Gray, Byte> skel = new Image<Gray, byte>(img2.Size);
skel.SetValue(0);
CvInvoke.cvThreshold(img2, img2, 127, 256, 0);
StructuringElementEx element = new StructuringElementEx(3, 3, 1, 1, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_CROSS);
bool done = false;
while (!done)
{
CvInvoke.cvErode(img2, eroded, element,1);
CvInvoke.cvDilate(eroded, temp, element,1);
temp = img2.Sub(temp);
skel = skel | temp;
img2 = eroded;
if (CvInvoke.cvCountNonZero(img2) == 0) done = true;
}
This code WORK but is very slow in video (sequential frames)
Image<Gray, byte> Skeleton(Image<Gray, byte> orgImg)
{
Image<Gray, byte> skel = new Image<Gray, byte>(orgImg.Size);
for (int y = 0; y < skel.Height; y++)
for (int x = 0; x < skel.Width; x++)
skel.Data[y, x, 0] = 0;
imageBoxOutputROI.Image = skel;
Image<Gray, byte> img = skel.Copy();
for (int y = 0; y < skel.Height; y++)
for (int x = 0; x < skel.Width; x++)
img.Data[y, x, 0] = orgImg.Data[y, x, 0];
StructuringElementEx element;
element = new StructuringElementEx(3, 3, 1, 1, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_CROSS);
Image<Gray, byte> temp;
bool done = false;
do
{
temp = img.MorphologyEx(element, Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_OPEN, 1);
temp = temp.Not();
temp = temp.And(img);
skel = skel.Or(temp);
img = img.Erode(1);
double[] min, max;
Point[] pmin, pmax;
img.MinMax(out min, out max, out pmin, out pmax);
done = (max[0] == 0);
} while (!done);
return skel;
}
Input image:
I need a help to implement the skeletonization code.
A research in below sites but i not hace success:
http://felix.abecassis.me/2011/09/opencv-morphological-skeleton/[^]
https://stackoverflow.com/questions/26850944/skeleton-of-an-image-in-emgucv[^]
https://stackoverflow.com/questions/26850944/skeleton-of-an-image-in-emgucv[^]
I am grateful for any help .
Richard J. Algarve
Try below code.
It works for me (My input image has white background). I think the problem with your code is Sub and Or operators.
public static Bitmap Skelatanize(Bitmap image)
{
Image<Gray, byte> imgOld = new Image<Gray, byte>(image);
Image<Gray, byte> img2 = (new Image<Gray, byte>(imgOld.Width, imgOld.Height, new Gray(255))).Sub(imgOld);
Image<Gray, byte> eroded = new Image<Gray, byte>(img2.Size);
Image<Gray, byte> temp = new Image<Gray, byte>(img2.Size);
Image<Gray, byte> skel = new Image<Gray, byte>(img2.Size);
skel.SetValue(0);
CvInvoke.Threshold(img2, img2, 127, 256, 0);
var element = CvInvoke.GetStructuringElement(ElementShape.Cross, new Size(3, 3), new Point(-1, -1));
bool done = false;
while (!done)
{
CvInvoke.Erode(img2, eroded, element, new Point(-1, -1), 1, BorderType.Reflect, default(MCvScalar));
CvInvoke.Dilate(eroded, temp, element, new Point(-1, -1), 1, BorderType.Reflect, default(MCvScalar));
CvInvoke.Subtract(img2, temp, temp);
CvInvoke.BitwiseOr(skel, temp, skel);
eroded.CopyTo(img2);
if (CvInvoke.CountNonZero(img2) == 0) done = true;
}
return skel.Bitmap;
}
I need to crop an image without changing its aspect ratio. I am taking picture from CANON1100D using EDSDK. Captured image:
Width = 1920 and Height=1280
Aspect ratio is 1.5. But I need picture which aspect ratio will be 1.33.
// convert into processing resolution (1600,1200)
Image<Bgr, byte> runtime_frm = new Image<Bgr, byte>(frame.ToBitmap(1600,1200));
// also in bitmap processing
// Bitmap a = new Bitmap(runtime_frm.ToBitmap());
// Bitmap b = new Bitmap(a, new Size(1600,1200));
It's resizing the image, so the aspect ratio of image is changed, but it creates stress in image. I'd like to crop the image (1920x1280) to (1600x1200) in runtime.
How can I do this programmatically?
public void Crop(Bitmap bm, int cropX, int cropY,int cropWidth,int cropHeight)
{
var rect = new System.Drawing.Rectangle(cropX,cropY,cropWidth,cropHeight);
Bitmap newBm = bm.Clone(rect, bm.PixelFormat);
newBm.Save("image2.jpg");
}
Maybe something like that?
source
this is my solution for centered cropping.
Bitmap CenterCrop(Bitmap srcImage, int newWidth, int newHeight)
{
Bitmap ret = null;
int w = srcImage.Width;
int h = srcImage.Height;
if ( w < newWidth || h < newHeight)
{
MessageBox.Show("Out of boundary");
return ret;
}
int posX_for_centerd_crop = (w - newWidth) / 2;
int posY_for_centerd_crop = (h - newHeight) / 2;
var CenteredRect = new Rectangle( posX_for_centerd_crop,
posY_for_centerd_crop, newWidth, newHeight);
ret = srcImage.Clone(imageCenterRect, srcImage.PixelFormat);
return ret;
}