我正在跟蹤基於顏色的對象,並且我正在使用EmguCV庫將我的彩色圖像限制爲二進制黑白圖像。閾值本身非常快,在320x240的圖像上爲50ms。我使用RG色度色彩空間,所以有一些必要的計算。如何加快我在C#中的顏色閾值#
現在我試圖用指針來加速它,但結果與我用emguCV做的(每幅圖像大約50ms)非常相似。
我想問問,如果有一些專家能夠幫助我,我做錯了什麼。這是我的顏色閾值實現的短代碼片段。它基於這個http://www.bobpowell.net/onebit.htm。
public static Bitmap ThresholdRGChroma(Bitmap original, double angleMin,
double angleMax, double satMin, double satMax)
{
Bitmap bimg = new Bitmap(original.Width, original.Height, PixelFormat.Format1bppIndexed);
BitmapData imgData = original.LockBits(new Rectangle(0, 0, original.Width, original.Height), ImageLockMode.ReadOnly, original.PixelFormat);
BitmapData bimgData = bimg.LockBits(new Rectangle(0, 0, bimg.Width, bimg.Height), ImageLockMode.ReadWrite, bimg.PixelFormat);
int pixelSize = 3;
double r, g, angle, sat;
unsafe
{
byte* R, G, B;
byte* row;
int RGBSum;
for (int y = original.Height - 1; y >= 0; y--)
{
row = (byte*)imgData.Scan0 + (y * imgData.Stride);
for (int x = original.Width - 1; x >= 0; x--)
{
// get rgb values
B = &row[x * pixelSize];
G = &row[x * pixelSize + 1];
R = &row[x * pixelSize + 2];
RGBSum = *R + *G + *B;
if (RGBSum == 0)
{
SetIndexedPixel(x, y, bimgData, false);
continue;
}
//calculate r ang g for rg chroma color space
r = (double)*R/RGBSum;
g = (double)*G/RGBSum;
//and angle and saturation
angle = GetAngleRad(r, g) * (180.0/Math.PI);
sat = Math.Sqrt(Math.Pow(g, 2) + Math.Pow(r, 2));
//conditions to set pixel black or white
if ((angle >= angleMin && angle <= angleMax) && (sat >= satMin && sat <= satMax))
SetIndexedPixel(x, y, bimgData, true);
else
SetIndexedPixel(x, y, bimgData, false);
}
}
}
bimg.UnlockBits(bimgData);
original.UnlockBits(imgData);
return bimg;
}
private unsafe static void SetIndexedPixel(int x, int y, BitmapData bmd, bool pixel)
{
int index = y * bmd.Stride + (x >> 3);
byte* p = (byte*)bmd.Scan0.ToPointer();
byte mask = (byte)(0x80 >> (x & 0x7));
if (pixel)
p[index] |= mask;
else
p[index] &= (byte)(mask^0xff);
}
private static double GetAngleRad(double x, double y)
{
if (x - _rgChromaOriginX == 0)
return 0.0;
double angle = Math.Atan((y - _rgChromaOriginY)/(x - _rgChromaOriginX)); // 10ms
if (x < _rgChromaOriginX && y > _rgChromaOriginY)
angle = angle + Math.PI;
else if (x < _rgChromaOriginX && y < _rgChromaOriginY)
angle = angle + Math.PI;
else if (x > _rgChromaOriginX && y < _rgChromaOriginY)
angle = angle + 2 * Math.PI;
return angle;
}
非常感謝。只有修改飽和度及其範圍才能加速大約20毫秒的閾值,從50到30. 我也發現這個不錯的[論文](http://www.lucs.lu.se/LUCS/M012/Minor12.pdf)關於RG色度,他們展示瞭如何通過去除Atan來加速它,就像你說的那樣。我會發布我的修正版本,它在我的計算機上的閾值爲320x240圖像,時間爲18ms。 – LadislavM 2012-03-11 10:51:43