最快的RGB颜色检测C ++

时间:2015-01-03 19:56:44

标签: c++ rgb detect getpixel bitblt

您好我使用了getpixel方法,bitblt或其所谓的(创建位图标题)然后遍历所有值。这非常慢。例如,如果我必须检测到红色或特定颜色的东西,则需要很长时间。有更快的方法吗?我确实尝试使用桌面作为HWND然后窗口我需要找到颜色,但桌面是某种程度上更快..猜测,因为它必须寻找窗口我猜。我使用这两种方法获得了高CPU使用率。

void Get_Color(int x,int y,int w,int h,int &red,int &green,int &blue,int action)
{
        HDC hdc, hdcTemp;
        RECT rect;
        BYTE*bitPointer;
        HWND Desktop = GetDesktopWindow();
        hdc = GetDC(Desktop);
        GetWindowRect(Desktop, &rect);
        hdcTemp = CreateCompatibleDC(hdc);
        BITMAPINFO bitmap;
        bitmap.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bitmap.bmiHeader.biWidth = w;
        bitmap.bmiHeader.biHeight = h;
        bitmap.bmiHeader.biPlanes = 1;
        bitmap.bmiHeader.biBitCount = 32;
        bitmap.bmiHeader.biCompression = BI_RGB;
        bitmap.bmiHeader.biSizeImage = 0;
        bitmap.bmiHeader.biClrUsed = 0;
        bitmap.bmiHeader.biClrImportant = 0;
        HBITMAP hBitmap2 = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
        HGDIOBJ save = SelectObject(hdcTemp, hBitmap2);
        BitBlt(hdcTemp, 0, 0, w, h, hdc, x, y, SRCCOPY);
        if(action==1)
        {
            for(int j=0;j<=w*h*4;j+=4)
            {
                red = bitPointer[j+2];
                green = bitPointer[j+1];
                blue = bitPointer[j];
                if(red<30 && green>190 && blue>190)
                {
                    break;
                }
            }   
        }
        else
        {
            for(int j=0;j<=w*h*4;j+=4)
            {
                red = bitPointer[j+2];
                green = bitPointer[j+1];
                blue = bitPointer[j];
                break;

            }   
        }
        ///RELEASE
        DeleteObject( SelectObject(hdcTemp, save) );
        DeleteDC(hdcTemp);
        DeleteDC(hdc);
        ReleaseDC(NULL,hdc);
        ReleaseDC(NULL,hdcTemp);

    }

3 个答案:

答案 0 :(得分:0)

您可能会尝试破坏搜索。首先在红色通道中搜索,当成功时查找蓝色和绿色值:

for (int j=0; j<=w*h*4; j+=4){
    red = bitPointer[j+2];
    if (red<30) {
        green = bitPointer[j+1];
        blue = bitPointer[j];
        if (green>190 && blue>190) {
            do_something;
        }
    } 
} 

您也可以尝试通过指针算法加速(但是一个好的编译器可以很容易地优化前者):

for (BYTE *pRed=bitPointer+2; pRed<=bitPointer+w*h*4; pRed+=4){
    if (pRed<30) {
        green = pRed[-1];
        blue = pRed[-2];
        if (green>190 && blue>190) {
            do_something;
        }
    } 
}

如果这还不够,您可以考虑使用线程将搜索分解为单独的小型搜索。

答案 1 :(得分:0)

我建议你从位图创建一个RGB值表。这只需要执行一次。

struct RGB
{
  unsigned int red;
  unsigned int green;
  unsigned int blue;
};

RGB rgb_pixels[MAX_ROWS][MAX_COLUMNS];

// ...
for (unsigned int row = 0; row < MAX_ROWS; ++row)
{
  for (unsigned int column = 0; column < MAX_COLUMNS; ++column)
  {
     unsigned red = get_red_value(row, column);
     unsigned green = get_green_value(row, column);
     unsigned blue  = get_blue_value(row, column);
     RGB pixel;
     pixel.red = red;
     pixel.green = green;
     pixel.blue  = blue;
     rgb_pixels[row][column] = pixel;
  }
}

每当你的程序需要来自位图的RGB信息时,索引数组(rgb_pixels) 对于您感兴趣的每个像素,访问RGB像素阵列将比搜索位图和转换要快得多。

答案 2 :(得分:0)

基本上每次调用方法时,它都会创建一个全新的位图并再次复制它。通过在Get_Color()调用之间保持颜色数组,可以最大程度地加速程序。您可以将其放在类或全局变量中。托马斯马修斯对此有一个好主意。一旦确定,Jean-BaptisteYunès就会有一些很好的建议。