2014-05-19 3 views
4

OpenCV 광학 흐름을 사용하여 머리 제스처를 감지하는 응용 프로그램을 개발했습니다. 계산 방법을 최적화하고 싶습니다. 왜냐하면 현재는 매우 느립니다. 더 나은, 빨리, 효율적인 방법으로 나에게 제안 해 주시겠습니까?OpenCV : 광학 유량 계산 최적화

현재 광학 흐름 방향을 결정하기 위해 두 프레임 사이의 모든 특징 지점의 X와 Y 좌표를 비교하고 있습니다. 나는 광학 흐름 방향을 찾기 위해 검사 할 피처의 수를 줄이고 싶습니다. 기능 집합을 가장 잘 나타내는 최소 특징 점을 선택하십시오. 당신이 당신의 문제의 크기에 타이밍을 확인하려면이 코드를 시도 할 수

@Override 
    public Mat onCameraFrame(Mat inputFrame) { 
     up.value = 0; 
     down.value = 0; 
     left.value = 0; 
     right.value = 0; 
     pq.clear(); 

     // start the timing counter to put the frame rate on screen 
     // and make sure the start time is up to date, do 
     // a reset every 10 seconds 
     if (lMilliStart == 0) 
      lMilliStart = System.currentTimeMillis(); 

     if ((lMilliNow - lMilliStart) > 10000) { 
      lMilliStart = System.currentTimeMillis(); 
      lFrameCount = 0; 
     } 

     inputFrame.copyTo(mRgba); 
     sMatSize.width = mRgba.width(); 
     sMatSize.height = mRgba.height(); 

     switch (viewMode) { 

     case VIEW_MODE_OPFLOW: 

      if (mMOP2fptsPrev.rows() == 0) { 

       // Log.d("Baz", "First time opflow"); 
       // first time through the loop so we need prev and this mats 
       // plus prev points 
       // get this mat 
       Imgproc.cvtColor(mRgba, matOpFlowThis, Imgproc.COLOR_RGBA2GRAY); 

       // copy that to prev mat 
       matOpFlowThis.copyTo(matOpFlowPrev); 

       // get prev corners 
       Imgproc.goodFeaturesToTrack(matOpFlowPrev, MOPcorners, iGFFTMax, 0.05, 20); 
       mMOP2fptsPrev.fromArray(MOPcorners.toArray()); 

       // get safe copy of this corners 
       mMOP2fptsPrev.copyTo(mMOP2fptsSafe); 
      } else { 
       // Log.d("Baz", "Opflow"); 
       // we've been through before so 
       // this mat is valid. Copy it to prev mat 
       matOpFlowThis.copyTo(matOpFlowPrev); 

       // get this mat 
       Imgproc.cvtColor(mRgba, matOpFlowThis, Imgproc.COLOR_RGBA2GRAY); 

       // get the corners for this mat 
       Imgproc.goodFeaturesToTrack(matOpFlowThis, MOPcorners, iGFFTMax, 0.05, 20); 
       mMOP2fptsThis.fromArray(MOPcorners.toArray()); 

       // retrieve the corners from the prev mat 
       // (saves calculating them again) 
       mMOP2fptsSafe.copyTo(mMOP2fptsPrev); 

       // and save this corners for next time through 
       mMOP2fptsThis.copyTo(mMOP2fptsSafe); 
      } 

      /* 
      * Parameters: prevImg first 8-bit input image nextImg second input 
      * image prevPts vector of 2D points for which the flow needs to be 
      * found; point coordinates must be single-precision floating-point 
      * numbers. nextPts output vector of 2D points (with 
      * single-precision floating-point coordinates) containing the 
      * calculated new positions of input features in the second image; 
      * when OPTFLOW_USE_INITIAL_FLOW flag is passed, the vector must 
      * have the same size as in the input. status output status vector 
      * (of unsigned chars); each element of the vector is set to 1 if 
      * the flow for the corresponding features has been found, 
      * otherwise, it is set to 0. err output vector of errors; each 
      * element of the vector is set to an error for the corresponding 
      * feature, type of the error measure can be set in flags parameter; 
      * if the flow wasn't found then the error is not defined (use the 
      * status parameter to find such cases). 
      */ 
      Video.calcOpticalFlowPyrLK(matOpFlowPrev, matOpFlowThis, mMOP2fptsPrev, mMOP2fptsThis, mMOBStatus, mMOFerr); 

      cornersPrev = mMOP2fptsPrev.toList(); 
      cornersThis = mMOP2fptsThis.toList(); 
      byteStatus = mMOBStatus.toList(); 

      y = byteStatus.size() - 1; 

      for (x = 0; x < y; x++) { 
       if (byteStatus.get(x) == 1) { 
        pt = cornersThis.get(x); 
        pt2 = cornersPrev.get(x); 
        double m = Math.abs(pt2.y - pt.y)/Math.abs(pt2.x - pt.x); 

        double distance= Math.sqrt(Math.pow((pt.x - pt2.x),2) + Math.pow((pt.y - pt2.y),2)); 

        if(distance < NOISE) 
         continue; 

        if (pt.x < pt2.x && pt2.y < pt.y) 

         if (m > 1) 
          up.value++; 
         else 
          right.value++; 

        else if (pt.x < pt2.x && pt2.y == pt.y) 
         right.value++; 

        else if (pt.x < pt2.x && pt2.y > pt.y) 
         if (m > 1) 
          down.value++; 
         else 
          right.value++; 

        else if (pt.x == pt2.x && pt2.y > pt.y) 
         down.value++; 

        else if (pt.x > pt2.x && pt2.y > pt.y) 
         if (m > 1) 
          down.value++; 
         else 
          left.value++; 

        else if (pt.x > pt2.x && pt2.y == pt.y) 
         left.value++; 

        else if (pt.x > pt2.x && pt2.y < pt.y) 
         if (m > 1) 
          up.value++; 
         else 
          left.value++; 

        else if (pt.x == pt2.x && pt2.y < pt.y) 
         up.value++; 

        Core.circle(mRgba, pt, 5, colorRed, iLineThickness - 1); 
        Core.line(mRgba, pt, pt2, colorRed, iLineThickness); 
       } 
      }//end of for 

      Direction r1, r2, r3; 

      if(up.value == 0 && left.value == 0 && right.value == 0 && down.value == 0) { 
       string = String.format("Direction: ---"); 
       showTitle(string, 3, colorRed); 

      }else{ 

       if (left.value < right.value) { 
        r1 = right; 
       } else r1 = left; 

       if (up.value < down.value) { 
        r2 = down; 
       } else r2 = up; 

       if (r1.value < r2.value) { 
        r3 = r2; 
       } else r3 = r1; 

       string = String.format("Direction: %s", r3.name); 

       for (HeadGestureListener listener : listeners) { 
        listener.onHeadGestureDetected(r3.name); 
       } 

       showTitle(string, 3, colorRed); 
      } 

      //Log.d("Mukcay",pq.poll().name); 
      // Log.d("Baz", "Opflow feature count: "+x); 
      if (bDisplayTitle) 
       showTitle("Optical Flow", 1, colorGreen); 
       break; 
     } 

     // get the time now in every frame 
     lMilliNow = System.currentTimeMillis(); 

     // update the frame counter 
     lFrameCount++; 

     if (bDisplayTitle) { 
      string = String.format("FPS: %2.1f", (float) (lFrameCount * 1000)/(float) (lMilliNow - lMilliStart)); 
      showTitle(string, 2, colorGreen); 
     } 

     if (System.currentTimeMillis() - lMilliShotTime < 1500) 
      showTitle(sShotText, 3, colorRed); 

     return mRgba; 
    } 
+0

갇혀 기록 - [* 이것이 당신이 아래로 못을 * 할 수있는 방법 (http://stackoverflow.com/a/378024/23771) 어디에 문제가 있습니다. 그러면 문제를 해결하는 방법을 알 수 있습니다. –

+0

나는 그런 종류의 최적화를 찾고 있지 않다. 나는 광학 흐름 방향을 계산하는 더 좋은 기술이 필요합니다. 어쨌든 고마워, 흥미로운 질문이었다. – Mukaddes

답변

0

:

http://graphics.berkeley.edu/papers/Tao-SAN-2012-05/

(코드 링크의 하단에 적합한 여기

내 코드입니다 페이지)

그러나 그것은 정말로 당신이 무엇을 의미하는지에 달려 있습니다. 다른 방법의 일부 상대 타이밍을 위해 여기에 확인할 수 있습니다

http://www.cvlibs.net/datasets/kitti/eval_stereo_flow.php?benchmark=flow

환호

여기
+0

크레딧 때문에 다른 링크를 게시 할 수 없습니다. 그러나 이것은 더 빨리 보이고, 주위에 작동한다 픽셀의 15 % [link] (http://www.nue.tu-berlin.de/menue/forschung/projekte/rlof/) – QED