2012-01-27 4 views
9

저는 C++ 및 OpenCV를 사용하여 실시간으로 웹캠에서 촬영 한 일부 이미지를 처리하고 있으며 시스템에서 가능한 최상의 속도를 얻으려고합니다.이미지 처리 속도 향상

처리 알고리즘을 변경하는 것 외에는 (지금은 변경할 수 없다고 가정). 처리 속도를 극대화하기 위해해야 ​​할 일이 있습니까?

아마도 멀티 스레딩이 여기에 도움이 될 수 있다고 생각하지만 실제로 (물론 분명히 전 C++에서는 멀티 스레딩을 사용했지만) 사실을 알지 못한다고 말하는 것은 부끄럽습니다.

x 코어 프로세서를 사용한다고 가정하면 x 스레드로 처리가 분할되어 실제로 속도가 향상됩니까? ... 또는이 스레드의 관리 오버 헤드가 20fps의 처리량 그것이 스레드 당 얼마나 많은 프로세싱이 수행 될지 알려주므로 대답에 영향을 줄 것이라고 가정하십시오.

멀티 스레딩 도움말은 여기에 있습니까?

OpenCV의 속도를 높이기위한 조언이 있습니까? 또는 내가 떨어 뜨릴 수있는 함정이 속도를 줄이는 방법이 있습니까?

감사합니다.

+1

들어오는 각 프레임을 회전하는 스레드 그룹에 던져 넣으면 죽은 단순한 멀티 스레딩을 허용해야합니다. –

답변

6

더 쉬운 방법, 내 생각, 수

스레드 풀을 사용하여 프레임 메모리 버퍼를 첫 번째 사용 가능한 스레드에 순차적으로 할당하고 관련 프레임의 알고리즘 단계가 완료되면 풀로 해제 할 수 있습니다.

현재의 (디버깅 된) 알고리즘은 변경되지 않지만 중간 결과를 버퍼링하는 데는 더 많은 메모리가 필요합니다. 당신의 작업에 대한 세부 사항없이,이 적절한 지 말하기 어렵다 물론

, ...

3

사용중인 특정 알고리즘이 멀티 스레드/병렬 플랫폼에 맞게 이미 최적화되어 있지 않으면 x 코어 프로세서에 던져 넣으면 아무 것도 할 수 없습니다. 알고리즘은 본질적으로 여러 스레드로부터 이익을 얻기 위해 스레드 가능해야합니다. 그러나 그것을 염두에두고 설계되지 않은 경우 변경해야합니다. 다른 한편, 많은 이미지 처리 알고리즘은 적어도 개념적으로 "embarassingly-parallel"입니다. 당신이 염두에두고있는 알고리즘에 대해 더 많은 정보를 공유 할 수 있습니까?

+0

글쎄요, 지금은 표준 OpenCV 알고리즘을 사용하여 처리의 "간격을 메우십시오". (그들은 다중 스레드/최적화 된 btw입니까?) ..... 실제로 사용할 알고리즘을 결정하지는 않았지만 필요에 따라 x 스레드로 나눌 수있는 픽셀 별 분석이 될 것입니다. 그들 모두가 결과를 돌려 주도록하십시오. – Cheetah

+0

알고리즘은 코드로 구현됩니다. 코드는 본질적으로 쓰레드에 안전하므로 데이터에 영향을받지 않습니다. –

+0

@MartinJames, 코드는 * 대부분 * 스레드로부터 안전합니다. 코드에서 가변적 인 정적 변수를 사용하지 않아야합니다. –

4

x 코어 프로세서가 있다고 가정 할 때 x 스레드로 처리를 분할하면 실제로 속도가 향상됩니까?

예, 사용되는 특정 알고리즘은 물론 동기화와 같은 작업을 처리하기위한 스레드 코드 작성 기술에도 크게 의존합니다. 그보다 더 나은 평가를 내리기에 충분한 세부 사항을 제공하지 않았습니다. 어떤 함수 f에 대한

for (i=0; i < DATA_SIZE; i++) 
{ 
    output[i] = f(input[i]); 
} 

:

일부 알고리즘의 형식은 것과 같은, 병렬화하기가 매우 쉽습니다. 이들은 으로 embarassingly parallelizable로 알려져 있습니다.; 데이터를 N 개의 블록으로 분할하고 N 개의 스레드가 각 블록을 개별적으로 처리하도록 할 수 있습니다. OpenMP와 같은 라이브러리는 이러한 종류의 스레딩을 매우 간단하게 만듭니다.

5

OpenCV에서 프로세서 나 알고리즘과 관련이없는 속도를 높이는 데 중요한 점이 하나 있는데, 행렬을 다룰 때는 여분의 복사를 피하는 것이 입니다. . 난 당신이 문서에서 가져온 예를 들어 줄 것이다 : 또 다른 행렬의 부분에 대한 헤더를 구성하여

"...을 그것은 단일 행, 단일 열, 여러 행, 여러 열, 직사각형이 될 수 (대수의 미성년자라고 함) 또는 대각선입니다. 새 헤더가 동일한 데이터를 참조하기 때문에 이러한 연산도 O (1)입니다.이 기능을 사용하여 실제로 행렬의 일부를 수정할 수 있습니다 , 예."

// add 5-th row, multiplied by 3 to the 3rd row 
M.row(3) = M.row(3) + M.row(5)*3; 

// now copy 7-th column to the 1-st column 
// M.col(1) = M.col(7); // this will not work 
Mat M1 = M.col(1); 
M.col(7).copyTo(M1); 

아마 당신은 이미이 문제를 알고 있지만, 나는 중요하고 효율적인 코딩 도구로 OpenCV의에서 헤더을 강조하는 것이 중요하다 생각합니다.

2

당신의 스레드가 다른 데이터에서 작동 할 수 있다면, 아마도 각 프레임을 대기, 그것을 떨어져 스레드 합리적인 것 같다 스레드 풀에 객체. 풀에서 나오는 처리 된 프레임이 동일한 순서로 전달되도록 프레임 객체에 시퀀스 번호를 추가해야 할 수도 있습니다.

1

OpenCV를 사용한 멀티 스레드 이미지 처리의 예제 코드는 다음과 같습니다. 내 코드를 체크 아웃 :

https://github.com/vmlaker/sherlock-cpp

그것은 내가 물체 검출의 성능을 향상시키기 위해 X 코어 CPU를 활용하고자하는 해낸거야. 프레임 메모리와 비디오 캡처의

  1. 분배 : detect 프로그램은 기본적으로 다중 스레드간에 작업을 분배하는 병렬 알고리즘, 모든 작업에 대해 별도의 파이프 라인 스레드입니다.
  2. 개체 검색 (각 Haar 분류 자당 하나의 스레드)
  3. 검색 결과로 출력을 확대하고 프레임을 표시합니다.
  4. 메모리 할당 해제.

모든 스레드간에 공유되는 캡처 된 프레임마다 메모리가 많아 성능과 CPU 사용률이 뛰어납니다.

+0

코드 주셔서 감사합니다. – CapelliC