【问题标题】:Fastest RGB color detection C++最快的 RGB 颜色检测 C++
【发布时间】:2015-01-03 19:56:43
【问题描述】:

您好,我使用了 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);

    }

【问题讨论】:

  • 您应该检测一次RGB,保存状态/值,并将其作为参数传递。无需在每次访问像素时检查 RGB。
  • 你能解释更多吗?我没有完全理解你.. :d
  • 你的意思是我不应该使用 for 循环来循环值?那我怎样才能得到颜色呢?
  • 我建议将位图转换为RGB值一次,然后您可以参考您的RGB结构。我建议使用 值的矩阵。您的代码每次都会从头开始搜索。
  • 你认为最占用CPU的操作是什么?因为它非常激烈。

标签: c++ rgb detect getpixel bitblt


【解决方案1】:

您可以尝试中断搜索。首先在红色通道中搜索,成功后查找蓝色和绿色值:

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

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

【讨论】:

    【解决方案2】:

    我建议您从位图中创建一个 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 像素数组将比搜索位图和转换要快得多。

    【讨论】:

      【解决方案3】:

      基本上每次调用方法时,它都会创建一个全新的位图并再次复制它。您可以通过在调用 Get_Color() 之间保留颜色数组来最大程度地加速您的程序。你可以把它放在一个类或一个全局变量中。 Thomas Matthews 对此有一个好主意。一旦解决了这个问题,让-巴蒂斯特·尤内斯 (Jean-Baptiste Yunès) 有一些很好的建议可供研究。

      【讨论】:

        猜你喜欢
        • 2016-02-29
        • 1970-01-01
        • 2019-07-02
        • 1970-01-01
        • 2013-05-06
        • 2011-05-09
        • 1970-01-01
        • 2011-04-27
        • 2021-04-22
        相关资源
        最近更新 更多