automatic movement when recognizing figure - c#

this code recognizes the image using ''template matching'', I would like the mouse to make a movement when recognizing the figure using mouse_event.
example: when recognizing person1, make the automatic movement using ''pattern'' and that I can place the angles to make the movement.
each character have their own ''pattern'', so I can put the moves!
namespace Auto_Person_Detection
{
public partial class Menu : Form
{
public Menu()
{
InitializeComponent();
Region = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(0, 0, Width, Height, 15, 15));
Detector.RunWorkerAsync();
}
private void Detector_DoWork(object sender, DoWorkEventArgs e)
{
Graphics g;
Bitmap bmp;
bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width / 8, Screen.PrimaryScreen.Bounds.Height / 4);
g = Graphics.FromImage(bmp);
Image<Gray, Byte>[] guns = new Image<Gray, Byte>[] {
new Image<Gray, Byte>(#"./img/Person1.png"),
new Image<Gray, Byte>(#"./img/Person2.png"),
new Image<Gray, Byte>(#"./img/Person3.png"),
new Image<Gray, Byte>(#"./img/Person4.png"),
new Image<Gray, Byte>(#"./img/Person5.png"),
new Image<Gray, Byte>(#"./img/Person6.png"),
new Image<Gray, Byte>(#"./img/Person7.png"),
new Image<Gray, Byte>(#"./img/Person8.png"),
new Image<Gray, Byte>(#"./img/Person9.png"),
new Image<Gray, Byte>(#"./img/Person10.png"),
new Image<Gray, Byte>(#"./img/Person11.png"),
new Image<Gray, Byte>(#"./img/Person12.png"),
new Image<Gray, Byte>(#"./img/Person13.png"),
new Image<Gray, Byte>(#"./img/Person14.png"),
new Image<Gray, Byte>(#"./img/Person15.png"),
new Image<Gray, Byte>(#"./img/Person16.png"),
new Image<Gray, Byte>(#"./img/Person17.png"),
new Image<Gray, Byte>(#"./img/Person18.png")
};

Related

Emgu CV Image sharpening and controur detection

I am working on a project where I need to identify dots from IR lasers on a surface. I use for that a camera with IR filter
Some input images:
There can be several dots, too. So I tried to sharpen this image from webcam and then use FindContours method of Emgu CV.
There is my code:
public static Image<Gray, byte> Sharpen(Image<Gray, byte> image, int w, int h, double sigma1, double sigma2, int k)
{
w = (w % 2 == 0) ? w - 1 : w;
h = (h % 2 == 0) ? h - 1 : h;
//apply gaussian smoothing using w, h and sigma
var gaussianSmooth = image.SmoothGaussian(w, h, sigma1, sigma2);
//obtain the mask by subtracting the gaussian smoothed image from the original one
var mask = image - gaussianSmooth;
//add a weighted value k to the obtained mask
mask *= k;
//sum with the original image
image += mask;
return image;
}
private void ProcessFrame(object sender, EventArgs arg)
{
Mat frame = new Mat();
if (_capture.Retrieve(frame, CameraDevice))
{
Image<Bgr, byte> original = frame.ToImage<Bgr, byte>();
Image<Gray, byte> img = Sharpen(frame.ToImage<Gray, byte>(), 100, 100, 100, 100, 30);
Image<Gray, byte> thresh = new Image<Gray, byte>(img.Size);
CvInvoke.PyrDown(img, thresh);
CvInvoke.PyrUp(thresh, thresh);
Image<Gray, byte> mask = new Image<Gray, byte>(thresh.Size);
Image<Gray, byte> cannyImg = thresh.Canny(10, 50);
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
Mat hierarchy = new Mat();
CvInvoke.FindContours(
cannyImg,
contours,
hierarchy,
RetrType.External,
ChainApproxMethod.ChainApproxSimple
);
Image<Bgr, byte> resultImage = img.Copy().Convert<Bgr, byte>();
int contCount = contours.Size;
for (int i = 0; i < contCount; i++)
{
using (VectorOfPoint contour = contours[i])
{
resultImage.Draw(CvInvoke.BoundingRectangle(contour), new Bgr(255, 0, 0), 5);
}
}
captureBox.Image = original.Bitmap;
cvBox.Image = resultImage.Bitmap;
}
}
Example of result image:
So it almost all the time works as I expect it to, but framerate is very low. I'm getting like 10-15 fps with resolution of 640x480. I need to be able to do the same thing for 1920x1080 with at least 30 fps. It's my first time with OpenCV and Emgu.CV. What can I do to make it perform better?
I solved this just setting the threshold, so that image turns black and white only. By adjusting the threshold I was able to achieve the same results if not better in terms of clarity, but also performance drastically improved since there is not heavy processing going on
Here is a snippet with ARCore library instead on EmguCV
var bitmap = eventArgs.Frame;
var filter = new Grayscale(0.2125, 0.7154, 0.0721);
var grayImage = filter.Apply(bitmap);
var thresholdFilter = new Threshold(CurrentThreshold);
thresholdFilter.ApplyInPlace(grayImage);
var blobCounter = new BlobCounter();
blobCounter.ProcessImage(grayImage);
var rectangles = blobCounter.GetObjectsRectangles();

How to get smooth edges in grabcut in Emgu c#

I have done the grabcut implementation interactive in c# but there is one problem which Iam unable to solve. How to smooth the edges. The edges looks rough after applying grabcut. I googled and found out a solution in c++ but I am unable to convert it into c#. Here What I have done so far.
Image<Bgr, Byte> image = new Image<Bgr, Byte>("SourceImage");
Image<Gray, Byte> mask1 = newMask;//Grabcut mask
Image<Bgr, float> maskF = mask1.Convert<Bgr, float>();
Image<Bgr, float> maskF2 = maskF.Mul(1 / 255);
Image<Bgr, float> imageF = image.Convert<Bgr, float>();
var img= imageF.Mul(maskF).Convert<Bgr, byte>();
Image<Bgr, byte> result3 = new Image<Bgr, byte>(imageSource.Width, imageSource.Height);
imageSource.Copy(result3, newMask);Pictureboxoutput.image=(result3+img).ToBitMap();
OutputImageInputImage

Disparity Map in Emgu.CV

I try to use disparity map calculation in C# using Emgu.CV
I read the images from this article as bitmapLeft and bitmapRight. For reference I used the example code from here
Here is my source code:
bitmapLeft = (Bitmap) mainForm.pictureBoxLeft.Image;
bitmapRight = (Bitmap)mainForm.pictureBoxRight.Image;
Image<Gray, Byte> imageLeft = new Image<Gray, Byte>(bitmapLeft);
Image<Gray, Byte> imageRight = new Image<Gray, Byte>(bitmapRight);
Image<Gray, Byte> imageDisparity = new Image<Gray, Byte>(bitmapLeft.Width, bitmapLeft.Height);
StereoBM stereoBM = new StereoBM(16, 15);
StereoMatcherExtensions.Compute(stereoBM, imageLeft, imageRight, imageDisparity);
Image bitmapDisparity = imageDisparity.ToBitmap();
However, the resulting bitmap is all black.
I think your problem is at the end. The result of calling StereoMatcherExtentions.Comput is a Mat/Image that has a depth of Cv16S, I converted that back to Cv8U and was able to display it. Here is my example. I used the same two images.
Mat leftImage = new Mat(#"C:\Users\jones_d\Desktop\Disparity\LeftImage.png", ImreadModes.Grayscale);
Mat rightImage = new Mat(#"C:\Users\jones_d\Desktop\Disparity\\RightImage.png", ImreadModes.Grayscale);
CvInvoke.Imshow("Left", leftImage);
CvInvoke.Imshow("Right", rightImage);
Mat imageDisparity = new Mat();
StereoBM stereoBM = new StereoBM(16, 15);
StereoMatcherExtensions.Compute(stereoBM, leftImage, rightImage, imageDisparity);
Mat show = new Mat();
imageDisparity.ConvertTo(show, DepthType.Cv8U);
CvInvoke.Imshow("Disparity", show);
CvInvoke.WaitKey(0);
Here are the images:
Which seems to match the result at: Depth Map from Image
Doug

Add two sub-images into one new image using emgu cv

I have two images with different dimensions and I want to create another large image includes them vertically.
private Image<Gray, Byte> newImage(Image<Gray, Byte> image1, Image<Gray, Byte> image2)
{
int ImageWidth = 0;
int ImageHeight = 0;
//get max width
if (image1.Width > image2.Width)
ImageWidth = image1.Width;
else
ImageWidth = image2.Width;
//calculate new height
ImageHeight = image1.Height + image2.Height;
//declare new image (large image).
Image<Gray, Byte> imageResult = new Image<Gray, Byte>(ImageWidth, ImageHeight);
imageResult.ROI = new Rectangle(0, 0, image1.Width, image1.Height);
image1.CopyTo(imageResult);
imageResult.ROI = new Rectangle(0, image1.Height, image2.Width, image2.Height);
image2.CopyTo(imageResult);
return imageResult;
}
The returned image is a black image and doesn't contain the two images, please help me where's the problem?
Thanks.
Your approach was correct. You simply had to remove the ROI. Just add at the end:
imageResult.ROI = Rectangle.Empty;
The Final Result shoul look like this:
imageResult.ROI = new Rectangle(0, 0, image1.Width, image1.Height);
image1.CopyTo(imageResult);
imageResult.ROI = new Rectangle(0, image1.Height, image2.Width, image2.Height);
image2.CopyTo(imageResult);
imageResult.ROI = Rectangle.Empty;
The solution in the following:
private Image<Gray, Byte> newImage(Image<Gray, Byte> image1, Image<Gray, Byte> image2)
{
int ImageWidth = 0;
int ImageHeight = 0;
//get max width
if (image1.Width > image2.Width)
ImageWidth = image1.Width;
else
ImageWidth = image2.Width;
//calculate new height
ImageHeight = image1.Height + image2.Height;
//declare new image (large image).
Image<Gray, Byte> imageResult;
Bitmap bitmap = new Bitmap(Math.Max(image1.Width , image2.Width), image1.Height + image2.Height);
using (Graphics g = Graphics.FromImage(bitmap))
{
g.DrawImage(image1.Bitmap, 0, 0);
g.DrawImage(image2.Bitmap, 0, image1.Height);
}
imageResult = new Image<Gray, byte>(bitmap);
return imageResult;
}

Finding contour points in emgucv

I am working with emguCV for finding contours essential points then saving this point in a file and user redraw this shape in future. so, my goal is this image:
example
my solution is this:
1. import image to picturebox
2. edge detection with canny algorithm
3. finding contours and save points
I found a lot of points with below codes but i can't drawing first shape with this point!
using Emgu.CV;
using Emgu.Util;
private void button1_Click(object sender, EventArgs e)
{
Bitmap bmp = new Bitmap(pictureBox1.Image);
Image<Bgr, Byte> img = new Image<Bgr, byte>(bmp);
Image<Gray, Byte> gray = img.Convert<Gray, Byte>().PyrDown().PyrUp();
Gray cannyThreshold = new Gray(80);
Gray cannyThresholdLinking = new Gray(120);
Gray circleAccumulatorThreshold = new Gray(120);
Image<Gray, Byte> cannyEdges = gray.Canny(cannyThreshold, cannyThresholdLinking).Not();
Bitmap color;
Bitmap bgray;
IdentifyContours(cannyEdges.Bitmap, 50, true, out bgray, out color);
pictureBox1.Image = color;
}
public void IdentifyContours(Bitmap colorImage, int thresholdValue, bool invert, out Bitmap processedGray, out Bitmap processedColor)
{
Image<Gray, byte> grayImage = new Image<Gray, byte>(colorImage);
Image<Bgr, byte> color = new Image<Bgr, byte>(colorImage);
grayImage = grayImage.ThresholdBinary(new Gray(thresholdValue), new Gray(255));
if (invert)
{
grayImage._Not();
}
using (MemStorage storage = new MemStorage())
{
for (Contour<Point> contours = grayImage.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage); contours != null; contours = contours.HNext)
{
Contour<Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.015, storage);
if (currentContour.BoundingRectangle.Width > 20)
{
CvInvoke.cvDrawContours(color, contours, new MCvScalar(255), new MCvScalar(255), -1, 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, new Point(0, 0));
color.Draw(currentContour.BoundingRectangle, new Bgr(0, 255, 0), 1);
}
Point[] pts = currentContour.ToArray();
foreach (Point p in pts)
{
//add points to listbox
listBox1.Items.Add(p);
}
}
}
processedColor = color.ToBitmap();
processedGray = grayImage.ToBitmap();
}
In your code you have added contour approximation operation
Contour<Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.015, storage);
This contour approximation will approximate your Contour to a nearest polygon & so your actual points got shifted. If you want to reproduce the same image you need not to do any approximation.
Refer this thread.

Categories