색상을 기반으로 개체를 추적하고 EmguCV 라이브러리를 사용하여 내 색상 이미지를 이진 흑백 이미지로 임계 값을 설정하려고했습니다. 임계 값 자체는 320x240 이미지에서 50ms로 매우 빨랐습니다. RG Chromaticity 색 공간을 사용하고 있으므로 반드시 계산해야합니다.C에서 내 색상 thresholding 속도를내는 방법
이제는 포인터를 사용하여 속도를 높이려고했지만 결과는 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;
}
고맙습니다. 채도와 범위를 수정하는 것만으로 50에서 30까지 약 20ms의 thresholding 속도가 향상됩니다. 나는이 멋진 [paper] (http://www.lucs.lu.se/LUCS/M012/Minor12.pdf) RG- 색도에 관해서는 Atan을 제거함으로써 당신이 말했던 것과 똑같이 속도를 향상시키는 법을 보여줍니다. 내 컴퓨터에서 임계 값 인 320x240 이미지를 18ms 이내에 게시합니다. – LadislavM