我正在使用Aforge.Net进行一些图像处理,而我无法理解the Grayscale filter。具体是三个强制性的红色/绿色/蓝色系数构造函数参数。
根据我的理解(从八年前进行的图像分割研究),灰度是一种不应该采用任何参数的操作。您拍摄图像,然后提取发光频道,就是这样。
那么这些参数是什么,我如何简单地提取发光?
更新 我应该澄清一下我要做的事情。我试图自动化一个我可以在GIMP中手动完成的过程。在GIMP中,我可以对任何图像应用阈值,并且它在发光直方图上操作以产生二进制图像,但是在Aforge中,阈值滤波器仅对灰度图像起作用。那么我将如何复制我的手动过程呢?
答案 0 :(得分:3)
当你在GIMP中转换为这样的灰度(见截图)时,它会在每个像素上调用它:
gint luminosity = GIMP_RGB_LUMINANCE (s[RED], s[GREEN], s[BLUE]) + 0.5;
看一下gimprgb.c的来源,可以看出它确实使用了这些值:
#define GIMP_RGB_LUMINANCE_RED (0.2126)
#define GIMP_RGB_LUMINANCE_GREEN (0.7152)
#define GIMP_RGB_LUMINANCE_BLUE (0.0722)
我将GIMP的输出图像与AForge使用这些参数生成的图像进行了比较:
var filter = new AForge.Imaging.Filters.Grayscale(0.2126, 0.7152, 0.0722);
它们看起来完全相同。
<强>更新强>
看来,使用阈值工具,GIMP采用快捷方式,只需取R,G或B的最大值。来自threshold.c:
if (tr->color)
{
value = MAX (s[RED], s[GREEN]);
value = MAX (value, s[BLUE]);
value = (value >= tr->low_threshold &&
value <= tr->high_threshold ) ? 255 : 0;
}
else
{
value = (s[GRAY] >= tr->low_threshold &&
s[GRAY] <= tr->high_threshold) ? 255 : 0;
}
这可能就是为什么你会得到不同的结果。
更新2:
.Net和其他地方的各种“转换为灰度”方法似乎都取平均值或使用上面提到的亮度或亮度数字的一些变化。我认为复制GIMP Threshold使用的最大值版本必须手工完成。我调整了here找到的一些快速(虽然不安全)代码来生成这个代码:
public static Bitmap ColorToGrayscaleWithMax(Bitmap original)
{
unsafe
{
Bitmap newBitmap = new Bitmap(original.Width, original.Height, PixelFormat.Format8bppIndexed);
BitmapData originalData = original.LockBits(
new Rectangle(0, 0, original.Width, original.Height),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData newData = newBitmap.LockBits(
new Rectangle(0, 0, original.Width, original.Height),
ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
//Set bytes per pixel
int colorBytesPerPixel = 3;
int grayBytesPerPixel = 1;
for (int y = 0; y < original.Height; y++)
{
//get the data from the original image
byte* oRow = (byte*)originalData.Scan0 + (y * originalData.Stride);
//get the data from the new image
byte* nRow = (byte*)newData.Scan0 + (y * newData.Stride);
for (int x = 0; x < original.Width; x++)
{
//create the grayscale pixel by finding the max color
byte grayScale = Math.Max(oRow[x * colorBytesPerPixel], oRow[x * colorBytesPerPixel + 1]);
grayScale = Math.Max(grayScale, oRow[x * colorBytesPerPixel + 2]);
//set the new image's pixel to the grayscale version
nRow[x * grayBytesPerPixel] = grayScale; //B
}
}
//unlock the bitmaps, finish
newBitmap.UnlockBits(newData);
original.UnlockBits(originalData);
return newBitmap;
}
}
然后您可以这样使用它:
var colorImage = AForge.Imaging.Image.FromFile(@"c:\temp\images\colorImage.png");
var preThresholdImage = ColorToGrayscaleWithMax(colorImage);
var filter = new AForge.Imaging.Filters.Threshold(100);
Bitmap bwImage = filter.Apply(preThresholdImage);
bwImage.Save(@"c:\temp\images\bwImage.png");
我在几张图片上运行它并与使用GIMP手动生成的图像进行比较,它们最终看起来完全相同。
答案 1 :(得分:1)
RGB到灰度转换需要RGB通道上的加权和。并且颜色发光的量度包括称为gamma correction的非线性变换。它也是加权和,但分别在R^gamma
,G^gamma
和B^gamma
上。描述了更多公式here。