You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Emgu提取图片ROI时第二PictureBox显示区域错误问题求助

问题根因及修复方案

核心问题

你选择ROI时用的是PictureBox控件的客户端坐标,和实际加载的原图像素坐标不匹配。只要PictureBox的SizeMode不是Normal,或者原图尺寸和PictureBox控件尺寸不一致,你画的选框坐标和原图实际像素坐标就会出现比例偏差,最终提取的ROI自然不符合预期。

修复步骤

  • 第一步:修改PictureBox的SizeMode属性为Normal,或者新增坐标转换逻辑,把控件坐标转换为原图像素坐标。如果需要保留Zoom/StretchImage等缩放模式,必须做坐标映射。
  • 第二步:优化ROI赋值逻辑,增加边界判断,避免ROI超出原图范围抛出异常。

参考修改代码

你可以替换button2_Click的逻辑,同时新增坐标转换方法:

// 控件坐标转原图像素坐标方法,当前适配StretchImage模式
private Point ControlToImagePoint(Point controlPoint)
{
    if (pictureBox1.Image == null) return controlPoint;
    float zoomX = (float)pictureBox1.Image.Width / pictureBox1.ClientSize.Width;
    float zoomY = (float)pictureBox1.Image.Height / pictureBox1.ClientSize.Height;
    return new Point((int)(controlPoint.X * zoomX), (int)(controlPoint.Y * zoomY));
}

private void button2_Click(object sender, EventArgs e)
{
    if (pictureBox1.Image == null || rect.IsEmpty) return;
    // 转换选框的坐标和尺寸到原图维度
    Point imgStart = ControlToImagePoint(rect.Location);
    Size imgSize = new Size(
        (int)(rect.Width * (float)pictureBox1.Image.Width / pictureBox1.ClientSize.Width),
        (int)(rect.Height * (float)pictureBox1.Image.Height / pictureBox1.ClientSize.Height)
    );
    Rectangle imgRoi = new Rectangle(imgStart, imgSize);
    // 边界校验,避免ROI超出原图范围
    imgRoi.X = Math.Max(0, imgRoi.X);
    imgRoi.Y = Math.Max(0, imgRoi.Y);
    imgRoi.Width = Math.Min(imgRoi.Width, pictureBox1.Image.Width - imgRoi.X);
    imgRoi.Height = Math.Min(imgRoi.Height, pictureBox1.Image.Height - imgRoi.Y);
    
    var img = new Bitmap(pictureBox1.Image).ToImage<Bgr, byte>();
    img.ROI = imgRoi;
    var imgROI = img.Copy();
    img.ROI = Rectangle.Empty;
    pictureBox2.Image = imgROI.AsBitmap();
}
  • 如果你用的是Zoom模式的SizeMode,需要额外计算统一缩放比例和坐标偏移,不能直接按宽高分别算比例。

内容的提问来源于stack exchange,提问作者dwk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 09:36:03