2014-11-01 3 views
0

다른 바이어 패턴을 가진 원본 이미지가 있습니다. 이것은 채널을 분리하기 위해 구현 한 것입니다. 이것은 수천 개의 큰 이미지에서 실행되기 때문에 속도가 매우 중요합니다.바이어 이미지를 컬러 채널로 분리 C++

코드 최적화를 제안 해주십시오. % (모듈러스)가 매우 빠르다는 것을 알고 있습니다. 예를 들어 이것을 어떻게 바꿀 수 있습니까?

감사

void Utilities::SeparateChannels(int** _image, int*& gr, int*& r, int*& b, int*& gb,int _width, int _height, int _colorOrder) 
{ 
    //swith case the color Order 
    int counter_R = 0; 
    int counter_GR = 0; 
    int counter_GB = 0; 
    int counter_B = 0; 

    switch (_colorOrder) 
    { 
     //rggb 
    case 0: 

     for (int i = 0; i < _height; i++) 
     { 
      for (int j = 0; j < _width; j++) 
      { 
       if (i % 2 == 0 && j % 2 == 0) 
       { 
        r[counter_R] = _image[i][j]; 
        counter_R++; 
       } 
       else if (i % 2 == 0 && j % 2 == 1) 
       { 
        gr[counter_GR] = _image[i][j]; 
        counter_GR++; 
       } 
       else if (i % 2 == 1 && j % 2 == 0) 
       { 
        gb[counter_GB] = _image[i][j]; 
        counter_GB++; 
       } 
       else if (i % 2 == 1 && j % 2 == 1) 
       { 
        b[counter_B] = _image[i][j]; 
        counter_B++; 
       } 
      } 
     } 
     break; 
    default: 
     break; 
    }  
} 
+2

실제로, 모듈은 일반적으로 * 매우 * 항상 상기 코드 판정 보인다 번째 오퍼랜드 2의 일정한 힘을 빠른 경우. 원한다면,'% 2' 대신에'& 1'을 시도해 볼 수도 있습니다.하지만 차이는 없습니다. –

답변

1

하나의 가능성 힘은 배열 자체로 대상 채널 데이터의 배열을 설정하는 것입니다 고려 가치가있을이 : 설정, 마찬가지로

int *channels[] = {r, gr, gb, b}; 

카운터로 배열 :

int counters[4] = {0}; 

... 다음 코드는 다음과 같이 나올 수 :

for (int i=0; i<_height; i++) 
    for (int j=0; j<_width; j++) { 
     channel = (i&1) << 1 + (j&1); 
     int &counter = counters[channel]; 

     channels[channel][counter++] = image[i][j]; 
    } 

기본적인 아이디어는 우리가 채널 주소로 사용할 수있는 단일 번호로 ij의 낮은 비트를 결합하는 것입니다. 그런 다음 해당 숫자를 사용하여 해당 채널의 채널 및 카운터에 색인을 생성합니다.

컴파일러가 이미 기존 코드를이 코드와 대략 동일하게 (또는이 코드가 생성하는 것보다 훨씬 더) 최적화 할 수는 있지만 가능하지는 않습니다.

나는 일반적으로 (적어도 일반적인 데스크톱 컴퓨터에서는) 많은 개선을 기대하지는 않습니다. 나는 당신이 루프를 작성하는 방법의 세부 사항과 거의 관계없이 병목 현상이 메인 메모리에 대한 대역폭이 될 것으로 기대한다.

1

2x2 블록으로 처리하려면 루프를 풀어야합니다. 이런 식으로 당신은 항상 패리티를 알게 될 것이고 그들을 테스트 할 필요가 없을 것입니다.

   r[counter_R] = _image[i][j]; 
       counter_R++; 

       gr[counter_GR] = _image[i][j+1]; 
       counter_GR++; 

       gb[counter_GB] = _image[i+1][j]; 
       counter_GB++; 

       b[counter_B] = _image[i+1][j+1]; 
       counter_B++; 

(또한 루프 파라미터를 적용).

+1

내가 맞으면 가장 가까운 이웃 재건을 계획하고 있습니다. 이것은 오히려 추한 결과를 줄 것입니다. (Bi) 선형 보간은 시각적으로 훨씬 좋습니다. 완전한 속도를 원하면 SSE 벡터화를 고려해야합니다 (그러나이 특정 변형의 경우 힘들 것입니다. 컴파일러가 도움을 줄 것으로 기대하지 마십시오). –

관련 문제