2015-01-03 32 views
0

안녕하세요 저는 getpixel 메서드, bitblt 또는 비트 맵 머리글 만들기라는 것을 사용하고 모든 값을 사용했습니다. 매우 느립니다. exapmple 위해 뭔가 빨간색 또는 특정 색을 감지해야했다면 매우 오랜 시간이 걸릴 것입니다. 더 빠른 길을 갈거야? 나는 바탕 화면을 HWND로 사용하려고 시도한 다음 색상을 찾을 필요가있는 창을 보았지만 바탕 화면은 어떻게 든 더 빨랐다. 창을 찾아야했기 때문에 추측했다. 두 방법 모두를 사용하여 높은 CPU 사용량을 얻습니다.가장 빠른 RGB 색감 C++

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

    } 
+0

RGB를 한 번 감지하고 상태/값을 저장 한 다음 매개 변수로 전달해야합니다. 모든 픽셀 액세스로 RGB를 확인할 필요가 없습니다. –

+0

더 설명 할 수 있습니까? 나는 꽤 당신을 잡을 수 없었다. : d –

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

충분하지 않은 경우 스레드를 사용하여 검색을 개별 병렬 검색의 작은 검색으로 나눌 수 있습니다.

+0

당신은 어떻게 생각합니까, mabey 그것은 한 스레드에 너무 많은가요? –

+0

원하는 성능에 따라 다릅니다 ... –

0

비트 맵에서 RGB 값 테이블을 만드는 것이 좋습니다. 이것은 한 번만 수행하면됩니다. 프로그램이 비트 맵, 인덱스에서 배열 (rgb_pixels를) 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 픽셀 배열에 액세스하는 것은 관심있는 각 픽셀에 대해 비트 맵을 검색하고 변환하는 것보다 훨씬 빠릅니다.

0

기본적으로 메서드를 호출 할 때마다 완전히 새로운 비트 맵을 만들고 다시 복사합니다. Get_Color() 호출 사이에 색상 배열을 유지하여 프로그램 속도를 최대화 할 수 있습니다. 클래스 나 전역 변수에 넣을 수 있습니다. Thomas Matthews는 좋은 생각을 가지고 있습니다. 일단 그것이 고쳐지면 Jean-Baptiste Yunès는 조사 할 충고가 있습니다.