openFrameworks × OpenCV에서 움직이는 물체를 감지하는 iOS 앱 만들기

openFrameworks와 ofxOpenCv를 사용하여 iPhone의 카메라 입력을 실시간으로 분석하고 움직이는 물체를 감지하는 샘플을 만드는 단계입니다.

ofxOpenCV와 ofVideoGrabber를 사용합니다.

관련 문서: openFrameworks - "iPhone의 카메라에서 입력을 실시간으로 처리하기위한 구현을 매우 간단하게 만들기 ofVideoGrabber - Qiita [Kita]

프로젝트 준비



프로젝트 만들기



videoGrabberExample 복사 및 이름 바꾸기

애드온 도입


  • 프로젝트의 addons 그룹에 ofxOpenCV 추가
  • [User Header Search Paths]에 "../../../addons/ofxOpenCv/libs"를 recursive로 추가합니다.

  • 구현



    헤더



    헤더를 include
    #include "ofxOpenCv.h"
    

    멤버 변수 추가
    ofxCvColorImage     colorImg;
    ofxCvGrayscaleImage grayImage;
    ofxCvGrayscaleImage grayBg;
    ofxCvGrayscaleImage grayDiff;
    ofxCvContourFinder  contourFinder;
    
    float   capW;
    float   capH;
    int     threshold;
    bool    bLearnBakground;
    

    터치 이벤트 핸들러



    화면을 탭하면 플래그가 true가 됩니다.
    void testApp::touchDown(ofTouchEventArgs & touch){
    
        bLearnBakground = true;
    }
    

    설정


    void testApp::setup(){  
    
        // フレームレート
        ofSetFrameRate(20);
    
        // ofVideoGrabber初期化
        grabber.initGrabber(320, 568, OF_PIXELS_BGRA);
    
        // 幅、高さ
        capW = grabber.getWidth();
        capH = grabber.getHeight();
    
        // 各Imageオブジェクトのメモリ確保
        colorImg.allocate(capW,capH);
        grayImage.allocate(capW,capH);
        grayBg.allocate(capW,capH);
        grayDiff.allocate(capW,capH);
    
        // フラグ、閾値を初期化
        bLearnBakground = true;
        threshold = 80;
    }
    

    이미지 분석



    매 프레임 불리는 처리. 여기서, 화상 해석을 행한다.
    void testApp::update(){
    
        ofBackground(255,255,255);
    
        // カメラ入力取得
        grabber.update();
        colorImg.setFromPixels(grabber.getPixels(), capW, capH);
        grayImage = colorImg;
    
        // 背景画像取得
        if (bLearnBakground == true) {
    
            grayBg = grayImage;
            bLearnBakground = false;
        }
    
        // 差分画像を計算
        grayDiff.absDiff(grayBg, grayImage);
        grayDiff.threshold(threshold);
    
        // 輪郭抽出
        contourFinder.findContours(grayDiff,        // input
                                   20,              // minArea
                                   (capW*capH)/3,   // maxArea
                                   10,              // nあered
                                   true);           // find holes
    }
    

    여기서 수행하는 이미지 분석 알고리즘
  • 카메라 입력 획득
  • 배경 이미지 얻기
  • 1과 2의 차이 이미지 계산
  • 윤곽 추출

  • 윤곽 추출에는 ofxCvContourFinder::findContours()을 이용.

    그리기



    얻어진 각종 화상을 화면상에 묘화.
    void testApp::draw(){   
    
        ofPushMatrix();
        ofScale(0.5, 0.5, 1);
        ofSetHexColor(0xffffff);
    
        // カメラ入力を描画
        grabber.draw(0, 0);
    
        // カメラ入力をグレー化した画像を描画
        grayImage.draw(320, 0);
    
        // 背景画像を描画
        grayBg.draw(0, capH);
    
        // 差分画像を描画
        grayDiff.draw(320, capH);
    
        // blob領域を描画
        for (int i = 0; i < contourFinder.blobs.size(); i++){
    
            contourFinder.blobs[i].draw(capW, capH);
        }
    
        ofPopMatrix();
    }
    

    완성





    왼쪽 상단에서 오른쪽 하단으로,
  • 원본 이미지
  • 원본 이미지의 회색 이미지
  • 배경 이미지
  • 차이 이미지

  • 가 표시되고 차이 이미지에 하늘색으로 윤곽이 핑크색으로 블로그 영역이 그려져 있습니다.

    (본래는 카메라에 손을 대면 손의 윤곽을 검출해, 손가락을 blob로서 추출해 주는 샘플입니다만, 스쿠쇼를 취하는데 양손이 필요해, 자동 녹화를 넣는 것도 귀찮았기 때문에 , 결국 손도 들지 않는 스쿠쇼가 되고 있습니다.그리고, 스쿠쇼 취할 때에 흔들리고 있습니다.)

    그리고, 여기까지 써 두고 있습니다만, 실은, opencvExample 로
    #define _USE_LIVE_VIDEO
    

    그러면 이것과 거의 같은 구현이 됩니다.

    어떠한 조사



    ofVideoGrabber에서 iPhone 전면 카메라를 사용하는 방법


  • ofVideoGrabber 의 헤더를 봐도, 직접 세트 할 수 있을 것 같은 메소드나 정수의 정의는 보이지 않았다.
  • setDeviceID(int _deviceID)listDevices() 라는 메소드가 있다
  • listDevices에서 전면 카메라 장치 ID를 찾고 setDeviceID로 설정하면 사용할 수 있습니다

  • 최악, AVFoundationVideoGrabber 수정
  • 좋은 웹페이지 즐겨찾기