你好我试图消除保存在位图中的图像的所有橙色色调,我需要在图像中用tesseract进行OCR,扫描文档的橙色似乎阻碍了文本中产生错误的过程,我尝试用photoshop删除橙色I,使OCR和效果完美,主要问题是像素不是全部相同的颜色,它们是橙色但是颜色不同
Bitmap modificar = new Bitmap("imagenamodificar.png");
for (int ycount2 = 0; ycount2 < modificar.Height; ycount2++)
{
for (int xcount2 = 0; xcount2 < modificar.Width; xcount2++)
{
if (modificar.GetPixel(xcount2, ycount2) == Color.Orange)
{
modificar.SetPixel(xcount2, ycount2, Color.White);
}
}
}
此代码绝对没有任何内容,图像保持不变。
然后我发现要与像素(0,0)进行比较,因为它总是我想要消除的颜色。
Bitmap modificar = new Bitmap("imagenamodificar.png");
for (int ycount2 = 0; ycount2 < modificar.Height; ycount2++)
{
for (int xcount2 = 1; xcount2 < modificar.Width; xcount2++)
{
if (modificar.GetPixel(xcount2, ycount2) == modificar.GetPixel(0,0))
{
modificar.SetPixel(xcount2, ycount2, Color.White);
}
}
}
但问题是它只删除了一小部分,橙色像素仍然存在,因为正如我之前提到的,并非所有橙色调都相同,有人能想到什么吗?
答案 0 :(得分:2)
以下是一些可以帮助您的关键点
GetPixel
SetPixel
,这是非常慢的unsafe
指针访问,并致电lockbits
获取Pinned Array
可以通过以下方法计算简单的颜色阈值(您也可以在Hue上计算)
<强>鉴于强>
threshold
有些int
<强>阈值强>
var thresh = threshold * threshold;
// decode the RBG from the image Pointer
var r = ((*p >> 16) & 255) - sR;
var g = ((*p >> 8) & 255) - sG;
var b = ((*p >> 0) & 255) - sB;
// compare it against the threshold
if (r * r + g * g + b * b > thresh)
continue;
注意: TaW 在评论中给出的链接非常有助于确定色彩距离。
使用lockbits
访问 Scanlines 和 Pin 我们的内存
Bitmap.LockBits Method (Rectangle, ImageLockMode, PixelFormat)
将位图锁定到系统内存中。
<强>代码强>
private static unsafe void ConvertImage(string fromPath, string toPath, Color source, Color targetColor, double threshold)
{
var thresh = threshold * threshold;
var target = targetColor.ToArgb();
using (var bmp = new Bitmap(fromPath))
{
// lock the array for direct access
var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);
// Convert the source to rgb
int sR = source.R, sG = source.G, sB = source.B;
// store the max length so we don't have to recalculate it
var length = (int*)data.Scan0 + bmp.Height * bmp.Width;
for (var p = (int*)data.Scan0; p < length; p++)
{
// get the rgb Distance
var r = ((*p >> 16) & 255) - sR;
var g = ((*p >> 8) & 255) - sG;
var b = ((*p >> 0) & 255) - sB;
// compare it against the threshold
if (r * r + g * g + b * b > thresh)
continue;
// poke the target color in
*p = target;
}
// unlock the bitmap
bmp.UnlockBits(data);
bmp.Save(toPath);
}
}
<强>用法强>
ConvertImage(@"d:\test.jpg", @"D:\result.bmp", Color.FromArgb(247, 107, 1), Color.Black, 25);
注意:我正在使用jpg色轮,因此它不是那么干净
原始图片
门槛25
阈值75
门槛150
橙色测试阈值75
unsafe关键字表示不安全的上下文,这是必需的 涉及指针的任何操作
Unsafe Code and Pointers (C# Programming Guide)
在公共语言运行库(CLR)中,不安全代码被称为 无法验证的代码。 C#中的不安全代码不一定是危险的;它 只是CLR无法验证其安全性的代码。 CLR会 因此,只有在完全信任的情况下才执行不安全的代码 部件。如果您使用不安全的代码,您有责任确保 您的代码不会引入安全风险或指针错误。