2014-07-23 2 views
4

현재 Android 및 iOS를 대상으로하는 C + +로 크로스 플랫폼 응용 프로그램을 개발하고 있습니다. 전반적으로 그것은 꽤 잘 작동하고 놀라운 성능을 가지고 있지만 iPhone 4 (S)에서는 매우 느리게 실행됩니다 (아래 그림 참조).iPhone4에서 OpenCV cvtColor() 성능 문제가 발생했습니다.

목표는 특정 알고리즘을 사용하여 ~ 5-10fps의 비디오 스트림을 처리하는 것입니다. 4

  • 넥서스 5

    • 넥서스
    • 갤럭시 S 미니
    • :

      다른 게다가,이 코드는 성공적 (5 초당 처리 프레임)과 다음의 장치 프로파일을 시험 하였다

    • 갤럭시 S3
    • 소니 XPeria Z
    • Google Nexus 1 (예, 여기에서도 작업 중)
    • 백45경1천5백15조5백36억9천1백36만3천2백10
    • 웨이 P1 및 P2
    • 갤럭시 참고

    • 아이 패드 미니

    • 아이폰 5
    • 아이폰 5S

    한 바와 같이, 그러나, 아이폰 4 하지 작업을 수행 및 iPhone 4가 있습니다. 둘 다 물론 => 0.5fps

    , 이것은는 화웨이와 같은 "약한"장치 및 심지어 넥서스 원 (2fps) 작업 때문에 조금 이상한 것 같다 2 초마다 1 프레임을 처리하는, 그래서 시작 성능 및 메모리 소비를 위해 Instruments와 프로파일 링.

    Memory usage of the app

    메모리 소비가 (당신이 이미지에서 볼 수있는) 가장 16메가바이트에서 사용되는, 괜찮습니다. 그러나 런타임의 프로파일 링은 약간 충격을 받았습니다.

    Runtime Profiling

    그리고 역 호출 트리 : - 거대한 공유에 대한 기능 (CV : RGB2RGB)

    Runtime Profiling with inverse call tree

    이제, 당신이 CPU를 볼 수있는 것은 cvtColor() 중입니다 총 런타임 중. 내부적으로 parallel_for 구현이 사용됩니다. 아마도 CPU가 해당 코드를 실행하는 데 적합하지 않을 수 있습니다. 또는 BNC2Gray 변환이 훨씬 빠르게 실행되는 것처럼 보이기 때문에 OpenCV에서 이상하게 구현 된 cv :: RGB2RGB 함수일까요?

    OpenCV v2.4.9 for iOS의 최신 미리 컴파일 된 버전을 사용합니다. 질문에있는 코드 조각은 기본적으로 BGRA에서 그레이 스케일로의 색상 변환 만합니다. 모양은 다음과 같습니다.

    Mat colorMat; 
    Mat gray;  
    
    colorMat = Mat(vHeight,vWidth,CV_8UC4, rImageData); // no data is copied 
    cvtColor(colorMat,colorMat,CV_BGRA2BGR); 
    cvtColor(colorMat,gray,CV_BGR2GRAY); 
    

    추가 처리에는 RGB 및 회색 정보가 필요하므로 2 단계로 나누어 처리합니다. 이는 전환 단계가 아닌 이유입니다.

    타측 비고 : I 또한 OpenCV for iOS samples 시험 (30fps의 촬상 레이트로 시작하는 경우) 전송 (12 장 처리 비디오) :

    • 아이폰 4 : 5.6 FPS
    • 시오 미니 : 30.4 FPS

    내 질문에 는 위스콘신에 매우 잘 작동되기 때문에 장치의 범위와 iOS 장치에서도 iPhone 4의 하드 또는 소프트웨어와 관련이 있어야한다고 결론을 내립니다.

    아마도 여기에 잘못 될 가능성에 대한 단서가 있습니까? 아무도 비슷한 문제를 경험 했습니까? 동일한 실적 문제 (예 : herehere)를 겪고있는 사람들에 대해 인터넷에서 희소 한 정보를 발견했습니다.

    다른 비디오 크기가 있다는 사실을 알고 있지만 1280x720 픽셀의 이미지에 대한 두 가지 "간단한"색상 변환은 약 2 초 동안 소모하지 않아야합니다. 특히 최근의 장치 인 iPhone 4 (S)가!

    이러한 방식으로 도움, 힌트 또는 경험을 주시면 대단히 감사하겠습니다!

    진행 및 추가 연구 결과 내가 대체 솔루션으로 실험 레미의 의견을 바탕으로

    . 불행하게도 나는 또한 다음의 (매우 사소한) 것은 작동하지 않습니다 '라고해야 : 자료 때문에,

    2014-07-24 09:07:41.763 CheckIfReal[604:3d03] AvCore-Debug: (Debug, Tag=CoreManager) Frame accepted (/Users/tbergmueller/Documents/dev/AvCore/avcore/CoreManager.cpp, line 591) 
    
    2014-07-24 09:07:41.765 CheckIfReal[604:3d03] AvCore-Debug: (Debug, Tag=CoreManager) starting (/Users/tbergmueller/Documents/dev/AvCore/avcore/CoreManager.cpp, line 636) 
    
    2014-07-24 09:07:41.771 CheckIfReal[604:3d03] AvCore-Debug: (Debug, Tag=CoreManager) first (/Users/tbergmueller/Documents/dev/AvCore/avcore/CoreManager.cpp, line 641) 
    
    2014-07-24 09:07:44.599 CheckIfReal[604:3d03] AvCore-Debug: (Debug, Tag=CoreManager) intermediate [720 x 1280] (/Users/tbergmueller/Documents/dev/AvCore/avcore/CoreManager.cpp, line 665) 
    
    2014-07-24 09:07:44.605 CheckIfReal[604:3d03] AvCore-Debug: (Debug, Tag=CoreManager) ending (/Users/tbergmueller/Documents/dev/AvCore/avcore/CoreManager.cpp, line 682) 
    

    따라서 매트 생성자 매트()가 빠른 :

    Mat colorMat, gray; 
    vector<Mat> channels; 
    AVDEBUG("starting", TAG,1); 
    colorMat = Mat(vHeight,vWidth,CV_8UC4, rImageData); // no data is copied 
    AVDEBUG("first", TAG, 1); 
    split(colorMat, channels); 
    AVDEBUG("intermediate " << colorMat.size(), TAG, 1); 
    // no BGRA2BGR conversion at all!! 
    gray = channels[0]; // take blue channel for gray 
    AVDEBUG("end", TAG, 1); 
    

    다음과 같은 출력을 생성합니다 (docs 참조). 그러나 split() 함수는이 코드 샘플을 거의 3 초 안에받습니다 !! 파란색 채널을 회색으로 표시 Mat-header 만 생성되기 때문에 Mat는 다시 빠릅니다.

    다시 말해 split()은 데이터를 복사하기 때문에 루프 구현에 문제가 있음을 다시 한번 나타냅니다. 이는 분명히 루프에서 수행됩니다.

  • +0

    http://stackoverflow.com/questions/11219240/maximum-speed-from-ios-ipad-iphone 내가 조사하고 발견 한 것입니다. 확신 할 수없는 경우. 예, 모든 세대의 i 디바이스는 이전 제품보다 훨씬 빠릅니다. 내 iPad3는 4S보다 훨씬 빠르며 4S는 iPad3보다 훨씬 빠릅니다. 새 iPad mini는 두 가지 모두를 능가하는 것 같습니다. –

    +0

    하드웨어 관련 질문에 대한 대답이 아니지만 in-place'cv :: cvtColor' 대신'cv :: split' 및'cv :: marge' 함수를 사용하여 일부 성능을 얻을 수 있습니다. 장소에서 채널을 제거하는 방법을 잘 모르겠습니다. 또는'colorMat'와는 다른 행렬에'cv :: cvtColor'를 호출하여 입력 AND 출력으로 시도해보고 알려주십시오. – remi

    +0

    의견에 감사드립니다. 나는 항상 모든 것을 깨끗하게 유지하기 위해 첫 번째 게시물을 편집 할 것입니다. 나는 주변에서 놀기 시작했고 프로파일 링의 초기 관찰을 따르지 않는 이상한 것들을 발견했습니다. 불행히도 오늘 자세히 조사 할 시간이 없으므로 내일 문제에 대한 자세한 내용을 알려 드리겠습니다. 그동안 고마워! –

    답변

    2

    의견을 보내 주시면 감사하겠습니다. 올바른 방향으로 나를 밀어 부쳤습니다.

    1280x720px가 iPhone 4에서 처리하기에는 너무 많은 데이터라는 예상과 마찬가지로 댓글에서 읽었을 때 해결 방법을 찾아야했습니다.

    대부분의 사람들이 알 수 있듯이 이미지 처리는 주로 회색조 이미지로 수행됩니다. iPhone 카메라에서 이미지를 BGRA로 캡처하면 CV_BGRA2GRAY (cv::cvtColor으로 가능)으로 변환하는 것을 의미합니다.

    이제 프로파일 링에서 알 수 있듯이이 변환에는 시간이 오래 걸리기 때문에 변환을 제거해야합니다. iPhone 4에서 가능한 한 가지 옵션은 BGRA 모드가 아니라 420YpCbCr 모드로 캡처하도록 카메라를 구성하는 것입니다. 카메라를 올바르게 구성하는 방법에 관한 StackOverflow-Topics가 있습니다. 나를 특히 thisthis as well 꽤 도움이되었다.

    음, 불행히도 iPhone 4는 3 개의 픽셀 형식 유형, 즉 420v, 420f 및 BGRA 만 지원합니다. 위의 정보와 링크를 사용하여 kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange (420v에 해당)로 이동하기로 결정했습니다. 가장 큰 이점은 하나의 이미지 평면에 회색 명암 이미지 (luma)가 있고 다른 이미지 평면에 색상 정보 (채도)가 있고이를 별도로 액세스 할 수 있다는 것입니다.

    핵심 아이디어는 회색 음영 이미지에서 관심 영역을 감지 한 다음 일반적으로 전체 이미지보다 훨씬 적은 흥미로운 픽셀에만 색상 공간 변환을 적용하는 것입니다. 실제로 컬러 이미지에서 그레이 스케일로 변환하지 않고 관심있는 작은 영역에만 컬러 공간 변환을 적용하면 iPhone 4의 알고리즘에서 초당 ~ 10 프레임까지 처리 속도가 올라가며 원하는 응용 프로그램에서 사용할 수 있습니다.

    관련 문제