2014-01-14 7 views
0

픽셀 단위로 분석하지 않고 두 이미지에 연산을 수행하는 방법이 있는지 알고 싶습니다. 나는 실시간으로 두 대의 카메라로 믹스 뷰를 만들려고한다. 그것으로 인해 최소한 초당 10 프레임의 속도로 작동해야합니다.버퍼를 사용하지 않고 2 개의 이미지 (덧셈, 뺄셈 등)에 대한 연산을 수행합니다.

     CPylonImage im1; 
       CPylonImage im2; 

    uint32_t width = im2.GetWidth(); 
     uint32_t height = im2.GetHeight(); 
     uint8_t* buffer1 = static_cast<uint8_t*>(im1.GetBuffer()); 
     uint8_t* p1 = buffer1; 
     uint8_t* buffer2 = static_cast<uint8_t*>(im2.GetBuffer()); 
     uint8_t* p2 = buffer2; 
     for (uint32_t y = 0; y < height; ++y) 
     { 
      for (uint32_t x = 0; x < width; ++x, ++p1) 
      { 
       *p2 = (uint8_t)*p1+*p2; 
       ++p2; 
      } 
     } 
     ShowImage(im2, "Mixed image"); 

을하지만이 너무 느렸다 : 내 프로그램의

첫 번째 버전은 다음과 같습니다.

답변에 대해 매우 감사드립니다.

+0

제목에 "버퍼없이"라고 표시되어 있지만 질문에 "픽셀 단위가 아닙니다."라고 표시되어 있습니다. 상호 배타적이지 않습니까? 너 진짜 원하는게 뭐야? "버퍼가 없다"는 것은 무엇을 의미합니까? 어떻게하면 각 픽셀에 대해 그렇게하지 않고 한 이미지를 다른 이미지에서 빼기를 기대합니까? – stijn

+2

SSE 명령을 사용하여 한 번에 4 바이트로 처리 할 수 ​​있습니다. 그러나 진짜 질문은 : 당신은 병목 현상이이 특정 행동에 있다는 것을 알 수 있습니까? 무슨 결의안을 말하고있는거야? – RedX

+0

명확하게하기 위해 이전 코드의 일부를 추가했습니다. 어쩌면 전체 이미지에 버퍼를 추가 할 수 있습니다. 내가 어떻게 만들 수 있니? 카메라의 해상도는 1294 픽셀 x 964 픽셀입니다. – CherryCola

답변

3

공유 한 코드에는 많은 문제가 있으며 댓글 섹션에는 작동하지 않는다고 명시되어 있습니다. 한 번에 한 가지 문제를 해결하는 데 초점을 맞추어야한다고 생각합니다. 코드가 실제로 작동하면 문제가 빨리 해결되도록하는 것이 좋습니다.

응용 프로그램이 한 이미지에서 width을 검색하고 다른 이미지에서 height을 검색합니다. 이것은 거의 좋은 일로 이어지지 않습니다. im1

uint32_t width = im1.GetWidth(); 
    uint32_t height = im2.GetHeight(); 

좋아, 그래서 buffer1 포인트 및 buffer1p1 점. 나는 당신이 정말로 p1을 필요로하지 않는다고 생각한다. 그냥 buffer1을 대신 사용하라. im1

uint8_t* buffer1 = static_cast<uint8_t*>(im1.GetBuffer()); 
    uint8_t* p1 = buffer1; 

그리고 지금 buffer2p2 점. 무엇?!im2이 아니어야합니까 ??? 당신은 정말로 p2을 필요로하지 않습니다.

uint8_t* buffer2 = static_cast<uint8_t*>(im1.GetBuffer()); 
    uint8_t* p2 = buffer2; 


    for (uint32_t y = 0; y < height; ++y) 
    { 

선언되지 않은 변수이며 다음 루프 단위 p. p1을 증가 시키려고했습니다.

 for (uint32_t x = 0; x < width; ++x, ++p) 
     { 
      *p2 = (uint8_t)*p1+*p2; 
      ++p2; 
     } 
    } 

지금은이 코드에 의해 수정되지 이후 감각 im2을 표시하지 않습니다. im1im2 크기가 다른이있는 경우

ShowImage(im2, "Mixed image"); 

한가지 더, 그것은 충돌이 발생할 수 있습니다.Short, Self Contained, Correct (Compilable), Example

그 연산의 처리 속도를 높일 수있는 몇 가지 기술이있다 :

나는 강하게 당신이 더 질문을하고 사람들이 도움을 얻는 방법을 알고 다음 포스트를 살펴 보시기 바랍니다 운영 :

  • 인텔 CPU를 사용하는 경우 : Intel® Threading Building Blocks (Intel® TBB);
  • Intel CPU를 사용하는 경우 : Intel® Integrated Performance Primitives (Intel® IPP);
  • OpenGL을 지원하는 GPU를 가지고 있다면 자신의 GLSL shader을 작성할 수 있습니다.
  • DirectX를 지원하는 GPU를 가지고 있다면 자신의 HLSL shader을 쓸 수 있습니다.
  • NVIDIA GPU를 사용하는 경우 : CUDA™;
  • NVIDIA/ATI GPU를 사용하는 경우 : OpenCL;
  • 선형 대수에 대한 C++ 템플릿 라이브러리 Eigen을 시도 할 수 있습니다 (행렬에 최적화 된 연산 수행).
  • OpenMP® (Fortran 및 C/C++ 프로그램에서 높은 수준의 병렬 처리를 지정하는 데 사용할 수있는 컴파일러 지시문, 라이브러리 루틴 및 환경 변수 집합에 대한 사양);
  • 마지막으로, 항상 어셈블리 코드를 작성하여 산술 연산을 수행 할 수 있습니다.
+0

실제 코드를 추가하지 않았습니다. Ijust는 그것을 기억에서 빨리 재건하려고 노력했다. 당신이 볼 수 있듯이 나는 그것을하고있는 동안 약간의 실수를했다. 두 이미지의 크기가 같습니다. 어쨌든 대답 주셔서 감사합니다 :) – CherryCola

+0

OpenCV는 관심있는 작업을 포함하여 많은 이미지 처리 기술을 제공하는 컴퓨터 비전을위한 프레임 워크입니다. 처리 속도를 높이기 위해 OpenCV는 위의 기술 중 몇 가지를 사용합니다. 오픈 소스 이후로 살펴볼 가치가 있으며 소스 코드를 살펴볼 수 있습니다. ;) – karlphillip

0

최적화를 시작하기 전에 출력이 올바른지 확인하십시오!

*p2 = (uint8_t)*p1+*p2; 

오버플하고 당신에게 잘못된 결과를 얻을 표현. 캐스트 (uint8_t)은 마법처럼 쓸모가 없습니다. 값을 유효한 범위로 잘라 내고 추가 결과 만 변환하십시오. 이 경우 피연산자는 uint8_t이므로 캐스트가 아무 것도하지 않습니다.

const uint16_t a = *p1; 
const uint16_t b = *p2; 
const uint16_t sum = a+b; 
*p2 = static_cast<uint8_t>(sum > 255 ? 255 : sum); 

는 더 나은 아직, 는 LSB하고 무점포이의 느슨한, 두 가지에 의해 유효한 범위에 머물 이런 식으로 결과 및 분할을 추가합니다.

*p2 = static_cast<uint8_t>(sum >> 1); 

다른 기술을 사용해야하기 전에 시도 할 수있는 몇 가지 팁이 있습니다.

  • 자동 벡터화를 지원하고 켜는 컴파일러 (vc> = 2012, gcc> = 4.7)를 사용하십시오.
  • Windows 32 비트 용으로 컴파일하는 경우 "/ arch : SSE2"를 사용하십시오.
  • constrestrict을 사용하여 컴파일러 힌트를 제공하십시오.
  • 당신은 창 크기가

예를 들어, 항상 같은, 사용 고정 폭과 높이가 있는지 확인하는 경우

void add(const CPylonImage& im1, CPylonImage& im2) 
{ 
    const int w = 1294; //im1.width(); 
    const int h = 964; //im1.height(); 

    const uint8_t* restrict buffer1 = static_cast<uint8_t*>(im1.getBuffer()); 
    uint8_t* restrict buffer2 = static_cast<uint8_t*>(im2.getBuffer()); 
    for(int i = 0; i < w*h; i++) 
    { 
     const uint16_t a = buffer1[i]; 
     const uint16_t b = buffer2[i]; 
     const uint16_t sum = a+b >> 1; 
     buffer2[i] = static_cast<uint8_t>(sum); 
    } 
}