简体   繁体   English

最快的RGB颜色检测C ++

[英]Fastest RGB color detection C++

Hi i have used getpixel method, bitblt or what its called (creating bitmap header) and then going though all the values. 嗨,我已经使用了getpixel方法,bitblt或它所调用的方法(创建位图标题),然后遍历所有值。 It is VERY slow. 非常慢。 For exapmple if i had to detect something red or specific color it would take very long time. 例如,如果我必须检测红色或特定颜色的东西,则将花费很长时间。 There has gotta be faster way right? 有更快的方法吧? I did try using desktop as HWND and then the window i need to find the colors, but desktop was somehow faster.. guesing because it had to look for the window i guess. 我确实尝试过将桌面用作HWND,然后我需要查找窗口,但是桌面以某种方式更快..猜测是因为它必须寻找我猜到的窗口。 I get HIGH cpu usage using both methods. 使用这两种方法,我的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);

    }

You may try to break your search. 您可以尝试中断搜索。 First search in the red channel and, when this succeed look for blue and green values: 首先在红色通道中搜索,成功后查找蓝色和绿色值:

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;
        }
    } 
} 

You can also try to accelerate via pointer arithmetic (but a good compiler will easily optimize the former): 您也可以尝试通过指针算术来加速(但是好的编译器可以轻松地优化前者):

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;
        }
    } 
}

If this is not sufficient, you may think about using threads to break the search into separate parallels smaller searches. 如果这还不够,您可能会考虑使用线程将搜索分成多个单独的并行较小搜索。

I suggest you create a table of RGB values from the bitmap. 我建议您从位图创建一个RGB值表。 This would only need to be performed once. 这仅需要执行一次。

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;
  }
}

Whenever your program needs RGB info from the bitmap, index the array ( rgb_pixels ). 每当您的程序需要位图中的RGB信息时,就对数组进行索引( rgb_pixels )。
Accessing the RGB pixel array will be much faster than searching the bitmap and converting, for each pixel you are interested in. 对于您感兴趣的每个像素,访问RGB像素阵列将比搜索位图并进行转换快得多。

Basically every time you call your method, it is creating an entirely new bitmap and copying it again. 基本上,每次调用方法时,它都会创建一个全新的位图并再次复制它。 You could speed up your program the most by keeping the array of colors between calls to Get_Color(). 通过在调用Get_Color()之间保留颜色数组,可以最大程度地提高程序速度。 You could put it in a class or a global variable. 您可以将其放在类或全局变量中。 Thomas Matthews has a good idea for that. 托马斯·马修斯(Thomas Matthews)为此有个好主意。 Once that's fixed, Jean-Baptiste Yunès has some good advice to look into. 解决此问题后,让-巴蒂斯特·尤涅斯(Jean-BaptisteYunès)将提供一些不错的建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM