Click here to Skip to main content
15,888,020 members
Please Sign up or sign in to vote.
1.00/5 (3 votes)
See more:
I am using C# EmguCv for detection of small circles in
Image
and I have already completed this part of the project by detecting all dots as
image
. So now I have two buttons 1st Point and 2nd Point. I want to add the functionality that on 1st Point button click and where I click with cursor pointing to circle, a small dot should be drawn in the center of the circle and clicking on the 2nd Point button the same process should be happen and a line from first drawn dot to second drawn dot as
image
. Now, when clicking the calculate button, then draw dot in center of all detected circles that are underlying the line. I have done
something
but it's not working as I want. The dot should only be drawn under that line.

What I have tried:

private void Firstpointbtn_Click(object sender, EventArgs e)
{
    // code to set the first point for "MANUAL" mode goes here
    MessageBox.Show("Fp click");
            
    if (img_path != null)
    {
        Image<Bgr, byte> imgin = new Image<Bgr, byte>(img_path);
        DisplayWindow2.Image = imgin.Bitmap;
        Drawshape = 1;
    }
    else
    {
        MessageBox.Show("Please Select Image");
    }
}

private void Secondpointbtn_Click(object sender, EventArgs e)
{
    // code to set the second point for "MANUAL" mode goes here
    MessageBox.Show("Sp click");
            
    if (img_path != null)
    {
        Drawshape = 2;
    }
    else
    {
        MessageBox.Show("Please Select Image");
    }           
}

private void DisplayWindow2_MouseDown(object sender, MouseEventArgs e)
{
    try
    {
        if (Drawshape == 1 || Drawshape == 2)
        {
            if (e.Button == MouseButtons.Left)
            {
                Graphics g = Graphics.FromImage(DisplayWindow2.Image);
                Pen p = new Pen(Color.Yellow, 1);
                var cursorPosition = DisplayWindow2.PointToClient(Cursor.Position);
                g.DrawEllipse(p, cursorPosition.X, cursorPosition.Y, 2, 2);
                MyCircles.Add(cursorPosition);
                DisplayWindow2.Refresh();

                // Save the center point of the circle
                if (Drawshape == 1)
                {
                    firstPoint = cursorPosition;
                }
                else if (Drawshape == 2)
                {
                    secondPoint = cursorPosition;
                }
            }
            if (p1.X == 0)
            {
                p1.X = e.X;
                p1.Y = e.Y;
            }
            else
            {
                p2.X = e.X;
                p2.Y = e.Y;
                p1List.Add(p1);
                p2List.Add(p2);
                //  p1.X = 0;
                DisplayWindow2.Invalidate();
            }
        }
    }
    catch (Exception exx)
    {
        MessageBox.Show(exx.Message);
    }
// } missing here

private void DisplayWindow2_Paint(object sender, PaintEventArgs e)
{
    if (DisplayWindow2.Image != null)
    {
        using (var p = new Pen(Color.Yellow, 1))
        {
            for (int x = 0; x < p1List.Count; x++)
            {
                e.Graphics.DrawLine(p, p1List[x], p2List[x]);
            }
            p.Dispose();
        }
    }
}

private void ManualCalculatebtn_Click(object sender, EventArgs e)
{
    MessageBox.Show("selected Manual and click on calculate");
            
    if (img_path != null)
    {
        try
        {
            Image<Bgr, byte> imgInput = new Image<Bgr, byte>(img_path);

            var temp = imgInput.Not().SmoothGaussian(5).Convert<Gray, byte>().ThresholdBinary(new Gray(220), new Gray(150));
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            Mat hierarchy = new Mat();
            CvInvoke.FindContours(temp, contours, hierarchy, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);
            Point startPoint = new Point(p1.X, p1.Y);
            Point endPoint = new Point(p2.X, p2.Y);
            double slope = (double)(endPoint.Y - startPoint.Y) / (double)(endPoint.X - startPoint.X);
            for (int i = 0; i < contours.Size; i++)
            {
                double area = CvInvoke.ContourArea(contours[i]);
                if (5 > area && area >= 30) continue;
                MCvMoments moments = CvInvoke.Moments(contours[i]);
                Point center = new Point((int)(moments.M10 / moments.M00), (int)(moments.M01 / moments.M00));
                       
                int radius = 3; // the radius of the object to be drawn
                // initialize the object's position to the center point
                double t = ((double)(center.X - p1.X) / (double)(p2.X - p1.X));// the angle at which the object moves (in degrees)
                int newX = (int)(p1.X + t * (p2.X - p1.X));
                int newY = (int)(p1.Y + t * (p2.Y - p1.Y));
                Point newCenter = new Point(newX, newY);
                      
                int angle = newX;
                double x = center.X + radius * Math.Cos(angle * Math.PI / 180); // calculate the x coordinate of the object's new position
                double y = center.Y + radius * Math.Sin(angle * Math.PI / 180); // calculate the y coordinate of the object's new position
                newCenter = new Point((int)x, (int)y); // update the object's position
                if (center.Y > startPoint.Y - slope * (center.Y - startPoint.X) && center.X > startPoint.X && center.X < endPoint.X)
                {
                    CvInvoke.Circle(imgInput, newCenter, 2, new MCvScalar(0, 0, 250), -1);
                }
            }
            DisplayWindow2.Image = imgInput.Bitmap;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
}
Posted
Updated 24-Feb-23 7:52am
v2

1 solution

Use the "line formula" (y = mx + c) of the line to verify if a point (x,y) is on (under) the line.

Equation of a Line from 2 Points[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900