gpt4 book ai didi

c# - 从位图中删除一种颜色的所有色调

转载 作者:行者123 更新时间:2023-12-02 20:27:22 24 4
gpt4 key购买 nike

你好,我正在尝试消除位图中保存的图像的所有橙色色调,我需要使用 tesseract 在图像中进行 OCR,而扫描文档的橙色似乎阻碍了在文本中产生错误的过程,我试过用 photoshop 去除橙色,使 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);
}
}
}

但问题是它只去除了一小部分,橙色像素仍然存在,因为正如我之前提到的,并非所有橙色调都相同,有人能想到什么吗?

最佳答案

这里有一些关键点可以帮助你一路走下去

  1. 不要使用GetPixel SetPixel,它非常慢
  2. 为了提高速度,最好使用 unsafe 和指针访问并调用 lockbits 来获得 Pinned Array
  3. 您可能想使用阈值来确定特定像素颜色是否接近您要删除的颜色

一个简单的颜色阈值可以通过以下计算(你也可以在 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;

Note : The link given in the comments by TaW is extremely helpful at figuring out color distance.

使用 lockbits 访问扫描线固定我们的内存

Bitmap.LockBits Method (Rectangle, ImageLockMode, PixelFormat)

Locks a Bitmap into system memory.

代码

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);

Note : i'm using a jpg color wheel so its not as clean as it could be


原图

enter image description here

阈值 25

enter image description here

阈值 75

enter image description here

阈值 150

enter image description here

橙色测试阈值 75

enter image description here

enter image description here


unsafe (C# Reference)

The unsafe keyword denotes an unsafe context, which is required for any operation involving pointers

Unsafe Code and Pointers (C# Programming Guide)

In the common language runtime (CLR), unsafe code is referred to as unverifiable code. Unsafe code in C# is not necessarily dangerous; it is just code whose safety cannot be verified by the CLR. The CLR will therefore only execute unsafe code if it is in a fully trusted assembly. If you use unsafe code, it is your responsibility to ensure that your code does not introduce security risks or pointer errors.

关于c# - 从位图中删除一种颜色的所有色调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49583891/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com