Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 有没有更好的方法来处理图像单击区域?_C#_Image_Picturebox - Fatal编程技术网

C# 有没有更好的方法来处理图像单击区域?

C# 有没有更好的方法来处理图像单击区域?,c#,image,picturebox,C#,Image,Picturebox,我有一个图像,你点击两个点,它会在每个点之间创建一条线。最后,该部门要求的是能够计算这些线路的长度以及这些线路发生的位置。他们目前正在用纸/笔/尺子手工完成这项工作。这是我正在处理的图像之一 中裂纹属于“面积7”, 所以我需要一种方法,除了保存我的x&y位置以便稍后测量这些线之外,还需要将它们出现的位置添加到我的列表中。下面是我知道的唯一一种方法,但事实证明它更混乱。因为图片不是一个完全的正方形或长方形,有很多重叠的区域和很多有空洞的区域,这些区域没有被很好地覆盖 有更好的方法吗?(目前,我只

我有一个图像,你点击两个点,它会在每个点之间创建一条线。最后,该部门要求的是能够计算这些线路的长度以及这些线路发生的位置。他们目前正在用纸/笔/尺子手工完成这项工作。这是我正在处理的图像之一

中裂纹属于“面积7”,

所以我需要一种方法,除了保存我的x&y位置以便稍后测量这些线之外,还需要将它们出现的位置添加到我的列表中。下面是我知道的唯一一种方法,但事实证明它更混乱。因为图片不是一个完全的正方形或长方形,有很多重叠的区域和很多有空洞的区域,这些区域没有被很好地覆盖

有更好的方法吗?(目前,我只是使用messagebox来显示我点击的位置,在我正确操作之前,我还没有对数据进行任何处理。)


我的建议是使用背景图像作为区域地图。此图像根本不会显示给用户。您只需加载一次并将其保存在内存中,但仍会像往常一样显示原始图像并在其上绘制线条。然后,当用户单击图像时,检查区域地图的颜色以确定区域

例如,假设我使用这两幅图像作为显示和区域地图:

private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
    var color = _zoneMap.GetPixel(e.X, e.Y);
    if (color == Color.FromArgb(0, 0, 255))
        MessageBox.Show("Zone 1");
    else if (color == Color.FromArgb(255, 0, 0))
        MessageBox.Show("Zone 2");
    else if (color == Color.FromArgb(0, 255, 0))
        MessageBox.Show("Zone 3");
    // etc...
}

这两个图像都加载到您的代码中,但仅向用户显示显示显示地图:

class MyForm
{
    Bitmap zoneDisplay;
    Bitmap zoneMap;

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        zoneDisplay = (Bitmap)Image.FromFile(@"c:\temp\zonedisp.png"); // replace with actual path to file
        zoneMap = (Bitmap)Image.FromFile(@"c:\temp\zonemap.png");

        // put the display image into the picturebox (or whatever control displays it)
        pictureBox.Image = zoneDisplay;
    }
然后,当用户单击图像时,只需检查区域地图上的颜色:

private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
    var color = _zoneMap.GetPixel(e.X, e.Y);
    if (color == Color.FromArgb(0, 0, 255))
        MessageBox.Show("Zone 1");
    else if (color == Color.FromArgb(255, 0, 0))
        MessageBox.Show("Zone 2");
    else if (color == Color.FromArgb(0, 255, 0))
        MessageBox.Show("Zone 3");
    // etc...
}
如果您的颜色有点不一致,那么您可能需要执行不太精确的比较。例如:

static int ColorDelta(Color c1, Color c2)
{
    return Math.Abs(c1.R - c2.R) + Math.Abs(c1.G - c2.G) - Math.Abs(c1.B - c2.B);
}

private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
    var color = _zoneMap.GetPixel(e.X, e.Y);
    if (90 > ColorDelta(color, Color.FromArgb(0, 0, 255)))
        MessageBox.Show("Zone 1");
    else if (90 > ColorDelta(color, Color.FromArgb(255, 0, 0)))
        MessageBox.Show("Zone 2");
    else if (90 > ColorDelta(color, Color.FromArgb(0, 255, 0)))
        MessageBox.Show("Zone 3");
    // etc...
}

图像是从您可以访问的矢量数据生成的,还是您基本上需要进行特征识别?如果是后者,这是一次性的,还是需要自动化?如果是一次性的,您可以为每个区域手动生成一个图像(例如,用黑色填充每个区域以获得相应的图像),并按像素测试用户单击的位置是否在该区域中。答案在很大程度上取决于你的限制。Re:在标题中包括“C#”,实际上我认为这是不受欢迎的。但也许“规则”已经改变了。“按要求编辑此内容以在标题中包含C”—这很奇怪,因为几年前有人绘制了这幅图像(可能是MS绘制的),以表示他们在熔炉中钎焊的零件。然后,他们只需打印成吨的页面。零件上任何未正确钎焊的“空隙”都会在纸上画一条线。因此,每个人在一天结束时可能会有10多页。因此,他们将在映像上创建这些行,提交到SQL server上的表,然后重置并为下一部分启动新映像。我希望这能有所帮助。@adv12我不知道,这是我帖子上的一个编辑请求,建议我做那个修改。听起来很棒。让我用我在办公室剩下的时间来处理一下,我会发回的。哦,如果不是很明显,你应该使用无损图像格式,比如BMP或PNG。不要在区域地图上使用JPG,因为它会扭曲颜色。我使用的是PNG。我打开了两份我的照片。我在画图中使用简单的RGB颜色(红、绿、蓝……等等)手动为区域的区域着色,使用上面的代码将它们加载到画图中并进行鼠标按下,但它似乎不起作用。只是在我的图像地图区域着色不是正确的方法吗?我对这个方法不太熟悉,但我不知道它在哪里比较这两幅图像,也许吧?听起来你做得对。也许你的RGB值有点偏离?您是否使用Paint中的“编辑颜色”窗口仔细检查了精确值?当你调用GetPixel时,你得到了什么颜色?例如,看起来像红色,在画图中正确显示了0,0255。好吧,这是我有点困惑的地方。我在
GetPixel
上停下来,点击显示的图像,我知道隐藏地图上有红色,这就是返回的
“{Name=ffed1c24,ARGB=(255,237,28,36)}”