Demo效果
视觉鼠标绘制与修改ROI(Region of Interest,感兴趣区域)是计算机视觉和图像处理中的常见任务。以下是实现这一功能的基本步骤和代码示例。
变量声明
//ROI显示序号
private int roiCounter = 1;
//存储ROI序号的的字典列表数据
private Dictionary<int, HTuple> roiDateDic = new Dictionary<int, HTuple>();
//存储ROI图形的的字典列表数据
private Dictionary<int, HObject> roiObjDic = new Dictionary<int, HObject>();
//编辑的ROI序号
private int editKey;
绘制ROI
private async void BtnDrawRoi_Click(object sender, EventArgs e)
{
showWorkMsg(listView1, "开始绘制", Color.DarkBlue);
await Task.Run(() =>
{
//绘制ROI
hSW.SetColor("yellow");
hSW.DrawRectangle1(out var R1, out var C1, out var R2, out var C2);
//生成ROI
HOperatorSet.GenRectangle1(out var rectangle, R1, C1, R2, C2);
//存储Roi数据
roiDateDic.Add(roiCounter, new HTuple(R1, C1, R2, C2));
//存储Roi图形
roiObjDic.Add(roiCounter, rectangle);
//显示ROI
//hSW.SetColor("green");
hSW.SetDraw("margin");
hSW.SetLineWidth(3);
hSW.DispRectangle1(R1, C1, R2, C2);
//将当前绘制ROI序号添加到列表框中(跨线程操作)
CmbROI.Invoke(() =>
{
//添加序号
CmbROI.Items.Add(roiCounter);
//设置当前选中
CmbROI.SelectedItem = roiCounter;
});
//设置显示序号,并且序号自加
HOperatorSet.DispText(hSW, roiCounter++, "image", R1, C1, "white", new HTuple("box_color"), new HTuple("red"));
});
showWorkMsg(listView1, "结束绘制", Color.DarkBlue);
}
UI
ContextMenuStrip菜单
#region ContextMenuStrip菜单
/// <summary>
/// 修改ROI
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void RoiXiuGai_Click(object sender, EventArgs e)
{
showWorkMsg(listView1, "开始修改ROI区域", Color.DarkBlue);
//需要编辑的ROI序号
var currentKey = editKey;
//在smartWindow中所有绘制都需要异步线程
await Task.Run(() =>
{
//判断ROI区域中是否存在该Key
if (roiDateDic.ContainsKey(currentKey))
{
//获取当前ROI
var roiData = roiDateDic[currentKey];
//清空对应ROI
hSW.DispObj(roiObjDic[currentKey]);
roiObjDic.Remove(currentKey);
ClearSelect();
hSW.SetColor("yellow");
//交互绘制
hSW.DrawRectangle1Mod(roiData[0], roiData[1], roiData[2], roiData[3], out var R1, out var C1, out var R2, out var C2);
//生成新区域
HOperatorSet.GenRectangle1(out var rectangle, R1, C1, R2, C2);
//重新保存区域
roiDateDic[currentKey] = new HTuple(R1, C1, R2, C2);
roiObjDic[currentKey] = rectangle;
//设置显示颜色
hSW.SetColor("red");
//显示区域
hSW.DispObj(rectangle);
//显示角标
HOperatorSet.DispText(hSW, currentKey, "image", roiData[0], roiData[1], "white", new HTuple("box_color"), new HTuple("red"));
//hSW.ClearWindow();
ClearSelect();
}
});
showWorkMsg(listView1, "结束修改ROI区域", Color.DarkBlue);
}
/// <summary>
/// 删除对应ROI
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void RoiRemove_Click(object sender, EventArgs e)
{
//需要编辑的ROI序号
var currentKey = editKey;
//移除对应对象
roiObjDic.Remove(currentKey);
roiDateDic.Remove(currentKey);
//刷新显示
ClearSelect();
}
#endregion
鼠标移动交互事件
/// <summary>
/// 鼠标交互事件
/// </summary>
private void hSmartWindowControl1_HMouseMove(object sender, HMouseEventArgs e)
{
//获取鼠标位置
var mX = e.X;
var mY = e.Y;
//遍历所有绘制的ROI数据
foreach (var roi in roiObjDic)
{
//获取当前数据和对象
var roiData = roiDateDic[roi.Key];
var roiObj = roi.Value;
//判断当前鼠标是否在Roi范围内
bool Isinside = IsRoiRectange(roiData, mX, mY);
if (Isinside)
{
hSW.SetColor("red");
//showWorkMsg(listView1, "选择ROI", Color.DarkBlue);
}
else
{
hSW.SetColor("green");
//showWorkMsg(listView1, "wei选择ROI", Color.DarkBlue);
}
hSW.DispObj(roiObj);
}
}
private bool IsRoiRectange(HTuple roiData, double mX, double mY)
{
hSW.SetDraw("margin");
//获取ROI位置
var R1 = roiData[0].D;
var C1 = roiData[1].D;
var R2 = roiData[2].D;
var C2 = roiData[3].D;
return mX > C1 && mX < C2 && mY > R1 && mY < R2;
}