C# opencvSharp实现鼠标移动选择感兴趣区域(ROI)主要通过鼠标响应事件来实现。
获取鼠标按下的开始坐标。
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
RectStartPoint = e.Location; //获得鼠标按下的pictureBox上坐标
Invalidate();
blnDraw = true;//判断标志
}
获得感兴趣区域框大小,显示感兴趣区域框以及坐标转换到原图像上。
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (blnDraw)
{
if (e.Button != MouseButtons.Left)//判断是否按下左键
{
return;
}
System.Drawing.Point tempEndPoint = e.Location; //记录框的位置和大小
//pictureBox上开始点坐标
Rect.Location = new System.Drawing.Point(
Math.Min(RectStartPoint.X, tempEndPoint.X),
Math.Min(RectStartPoint.Y, tempEndPoint.Y));
//pictureBox上矩形大小
Rect.Size = new System.Drawing.Size(
Math.Abs(RectStartPoint.X - tempEndPoint.X),
Math.Abs(RectStartPoint.Y - tempEndPoint.Y));
pictureBox1.Invalidate();
// 最后点位置
int X0, Y0;
Utilities.ConvertCoordinates(pictureBox1, out X0, out Y0, e.X, e.Y);
//在控件中
textBox1.Text = Convert.ToString("pictureBox最后点坐标" + e.X + " ," + e.Y); //pictureBox 上终点坐标
textBox2.Text = Convert.ToString("pictureBox开始点坐标" + Rect.X + " ," + Rect.Y); //开始点坐标
textBox3.Text = Convert.ToString("pictureBox的Width" + Rect.Width + " ," + Rect.Height);//大小
//Create ROI 感兴趣区域
Utilities.ConvertCoordinates(pictureBox1, out X0, out Y0, RectStartPoint.X, RectStartPoint.Y);
int X1, Y1;
Utilities.ConvertCoordinates(pictureBox1, out X1, out Y1, tempEndPoint.X, tempEndPoint.Y);
//感兴趣区域 左上点坐标-宽-高
RealImageRect.Location = new System.Drawing.Point(
Math.Min(X0, X1),
Math.Min(Y0, Y1));
RealImageRect.Size = new System.Drawing.Size(
Math.Abs(X0 - X1),
Math.Abs(Y0 - Y1));
textBox4.Text = "原图像上最后点坐标: X:" + X0 + " Y:" + Y0;
textBox5.Text = "原图像上RealImageRect: X:" + RealImageRect.X + " Y:" + RealImageRect.Y; // 原图像-左上点坐标
textBox6.Text = "原图像上RealImageRectSize: X:" + RealImageRect.Width + " Y:" + RealImageRect.Height; // 原图像-大小
Rect tmp_Rect = new Rect(RealImageRect.X,RealImageRect.Y, RealImageRect.Width, RealImageRect.Height);
ImageROI = new Mat(img, tmp_Rect);//新建一个mat,把roi内的图像加载到里面去。
//Cv2.ImWrite("4.jpg",ImageROI); //保存
}
}
将感兴趣区域在pictureBox2控件上显示。
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
// mouseUp 结束以后 将图像显示在pictureBox2控件中
pictureBox2.Image = ImageROI.ToBitmap();
/***************************************/
blnDraw = false; //结束绘制
}
感兴趣的框的绘制。
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (blnDraw)
{
if (pictureBox1.Image != null)
{
if (Rect != null && Rect.Width > 0 && Rect.Height > 0)
{
e.Graphics.DrawRectangle(new Pen(Color.Red, 1), Rect);//重新绘制颜色为红色
}
}
}
}
在本pictureBox 属性中sizeMode选择为 StretchImage,输入pictureBox控件上坐标转换为图像上实际的大小。
public class Utilities
{
//坐标转换
/**************************************
* 图片左边转换,
* Input输入: pictureBox 坐标X,Y
* Output输出: Image 图像上对应的坐标
**************************************/
public static void ConvertCoordinates(PictureBox pic,
out int X0, out int Y0, int x, int y)
{
int pic_hgt = pic.ClientSize.Height;
int pic_wid = pic.ClientSize.Width;
int img_hgt = pic.Image.Height;
int img_wid = pic.Image.Width;
X0 = x;
Y0 = y;
switch (pic.SizeMode)
{
case PictureBoxSizeMode.AutoSize:
case PictureBoxSizeMode.StretchImage:
X0 = (int)(img_wid * x / (float)pic_wid);
Y0 = (int)(img_hgt * y / (float)pic_hgt);
break;
}
}
}