gpt4 book ai didi

c# - 将 Rgb 图像转换为灰度 C# 代码时出现性能问题

转载 作者:太空狗 更新时间:2023-10-30 01:01:28 25 4
gpt4 key购买 nike

我正在为 Tesseract Ocr 编写一个 .Net 包装器,如果我使用灰度图像而不是 rgb 图像作为它的输入文件,那么结果会非常好。

所以我在网上搜索将 Rgb 图像转换为灰度图像的 C# 解决方案,我 found this code .

这会执行 3 个操作来提高 tesseract 的准确性。

  1. 调整图片大小
  2. 然后转换为灰度图像并去除图像中的噪声

现在这个转换后的图像给出了几乎 90% 的准确结果。

//Resize

public Bitmap Resize(Bitmap bmp, int newWidth, int newHeight)
{
Bitmap temp = (Bitmap)bmp;
Bitmap bmap = new Bitmap(newWidth, newHeight, temp.PixelFormat);

double nWidthFactor = (double)temp.Width / (double)newWidth;
double nHeightFactor = (double)temp.Height / (double)newHeight;

double fx, fy, nx, ny;
int cx, cy, fr_x, fr_y;
Color color1 = new Color();
Color color2 = new Color();
Color color3 = new Color();
Color color4 = new Color();
byte nRed, nGreen, nBlue;

byte bp1, bp2;

for (int x = 0; x < bmap.Width; ++x)
{
for (int y = 0; y < bmap.Height; ++y)
{
fr_x = (int)Math.Floor(x * nWidthFactor);
fr_y = (int)Math.Floor(y * nHeightFactor);

cx = fr_x + 1;
if (cx >= temp.Width)
cx = fr_x;

cy = fr_y + 1;
if (cy >= temp.Height)
cy = fr_y;

fx = x * nWidthFactor - fr_x;
fy = y * nHeightFactor - fr_y;
nx = 1.0 - fx;
ny = 1.0 - fy;

color1 = temp.GetPixel(fr_x, fr_y);
color2 = temp.GetPixel(cx, fr_y);
color3 = temp.GetPixel(fr_x, cy);
color4 = temp.GetPixel(cx, cy);

// Blue
bp1 = (byte)(nx * color1.B + fx * color2.B);
bp2 = (byte)(nx * color3.B + fx * color4.B);
nBlue = (byte)(ny * (double)(bp1) + fy * (double)(bp2));

// Green
bp1 = (byte)(nx * color1.G + fx * color2.G);
bp2 = (byte)(nx * color3.G + fx * color4.G);
nGreen = (byte)(ny * (double)(bp1) + fy * (double)(bp2));

// Red
bp1 = (byte)(nx * color1.R + fx * color2.R);
bp2 = (byte)(nx * color3.R + fx * color4.R);
nRed = (byte)(ny * (double)(bp1) + fy * (double)(bp2));

bmap.SetPixel(x, y, System.Drawing.Color.FromArgb(255, nRed, nGreen, nBlue));
}
}

//here i included the below to functions logic without the for loop to remove repetitive use of for loop but it did not work and taking the same time.
bmap = SetGrayscale(bmap);
bmap = RemoveNoise(bmap);

return bmap;
}

//SetGrayscale
public Bitmap SetGrayscale(Bitmap img)
{
Bitmap temp = (Bitmap)img;
Bitmap bmap = (Bitmap)temp.Clone();
Color c;
for (int i = 0; i < bmap.Width; i++)
{
for (int j = 0; j < bmap.Height; j++)
{
c = bmap.GetPixel(i, j);
byte gray = (byte)(.299 * c.R + .587 * c.G + .114 * c.B);

bmap.SetPixel(i, j, Color.FromArgb(gray, gray, gray));
}
}
return (Bitmap)bmap.Clone();
}

//RemoveNoise
public Bitmap RemoveNoise(Bitmap bmap)
{
for (var x = 0; x < bmap.Width; x++)
{
for (var y = 0; y < bmap.Height; y++)
{
var pixel = bmap.GetPixel(x, y);
if (pixel.R < 162 && pixel.G < 162 && pixel.B < 162)
bmap.SetPixel(x, y, Color.Black);
}
}

for (var x = 0; x < bmap.Width; x++)
{
for (var y = 0; y < bmap.Height; y++)
{
var pixel = bmap.GetPixel(x, y);
if (pixel.R > 162 && pixel.G > 162 && pixel.B > 162)
bmap.SetPixel(x, y, Color.White);
}
}
return bmap;
}

但问题是转换它需要很多时间

所以我包含了SetGrayscale(Bitmap bmap) RemoveNoise(Bitmap bmap) Resize() 方法中的函数逻辑,用于删除 for 循环的重复使用

但是并没有解决我的问题。

最佳答案

Bitmap 类的 GetPixel()SetPixel() 方法对于多次读/写来说是出了名的慢。访问和设置位图中单个像素的一种更快的方法是先锁定它。

有一个很好的例子here关于如何做到这一点,用一个很好的类 LockedBitmap 来环绕陌生人 Marshaling 代码。

本质上它所做的是使用 Bitmap 类中的 LockBits() 方法,为要锁定的位图区域传递一个矩形,然后复制这些像素从其非托管内存位置转移到托管内存位置,以便于访问。

这是一个关于如何将示例类与 SetGrayscale() 方法一起使用的示例:

public Bitmap SetGrayscale(Bitmap img)
{
LockedBitmap lockedBmp = new LockedBitmap(img.Clone());
lockedBmp.LockBits(); // lock the bits for faster access
Color c;
for (int i = 0; i < lockedBmp.Width; i++)
{
for (int j = 0; j < lockedBmp.Height; j++)
{
c = lockedBmp.GetPixel(i, j);
byte gray = (byte)(.299 * c.R + .587 * c.G + .114 * c.B);

lockedBmp.SetPixel(i, j, Color.FromArgb(gray, gray, gray));
}
}
lockedBmp.UnlockBits(); // remember to release resources
return lockedBmp.Bitmap; // return the bitmap (you don't need to clone it again, that's already been done).
}

这个包装类为我节省了大量的位图处理时间。一旦您在所有方法中都实现了这一点,最好只调用一次 LockBits(),那么我相信您的应用程序的性能将得到极大提高。


我还看到您经常克隆图像。这可能不会像 SetPixel()/GetPixel() 那样占用那么多时间,但它的时间仍然很重要,尤其是对于较大的图像。

关于c# - 将 Rgb 图像转换为灰度 C# 代码时出现性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38924901/

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