首页 > 解决方案 > 如何检测图像内容的结束位置?

问题描述

我收到大小相同但信息量不同的图像。下面的例子(红色边框是我的)。背景总是白色的。

我试图检测图像上的信息在哪里结束 - 在什么像素高度(并相应地裁剪)。换句话说,从底部找到第一个非白色像素。

除了从 Image 对象中提取 BitmapData 并遍历所有像素之外,还有更好的方法吗?

在此处输入图像描述 在此处输入图像描述

标签: c#.netsystem.drawing

解决方案


只是在查看您的图像和您的解决方案(如下)后添加一个建议,您的方法很好,但您可能能够提高效率。

您对自己的形象了解得越多越好;您确信背景始终是白色的(根据您的帖子,代码是一个更通用的实用程序,但以下建议仍然有效);如果该行不为空,您能否确信会在非白色像素中找到最远点?

例如; 在您的两张图片中,一行中最远的非白色像素约为 60 像素。如果这对您的数据普遍适用,那么您不需要扫描图像的整行,这将使您的 for 循环:

   for (int y = bitmap.Height - 1; y >= 0; y--) {
        for (int x = 0; x < 60; x++) {
            Color color = bitmap.GetPixel(x, y);
            if (color.R != backColor.R || color.G != backColor.G || color.B != backColor.B) {
                foundContentOnRow = y;
                break;
            }
        }
    }

(您可以将其作为函数的参数,以便在需要时轻松控制它)。

例如,想象第一行非白色行向下 80 像素。目前要找到它,您需要进行 640 x 300 = 192,000 次检查。如果您可以自信地说您会知道 100 像素内的一行是空白的(基于所提供的数据的高估),那么这将是每张图像 100 * 300 = 30,000 次检查。

如果您一直都知道图像的前 10 个像素始终是空白的,那么您可以再刮一点(比如 3000 次检查)。

在您知道第一个非白色像素在 10 到 60 像素之间(范围为 50)的设置上进行思考,您可以在 50 x 300 = 15,000 次检查中的第 80 行找到它,这是一个很好的减少。

当然,假设的缺点是,如果事情发生变化,您的假设可能无效,但如果数据将保持相当稳定,那么它可能是值得的,特别是如果您对大量图像执行此操作。


推荐阅读