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)
{
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)
{
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();
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);
DisplayWindow2.Invalidate();
}
}
}
catch (Exception exx)
{
MessageBox.Show(exx.Message);
}
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;
double t = ((double)(center.X - p1.X) / (double)(p2.X - p1.X));
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);
double y = center.Y + radius * Math.Sin(angle * Math.PI / 180);
newCenter = new Point((int)x, (int)y);
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);
}
}
}