2012-12-18 6 views
1

이 SURF 코드를 사용하여 이미지의 로고를 감지하고 있습니다. 그것은 잘 작동하지만 매우 느립니다. 어떻게 최적화 할 수 있습니까? 위의 코드 image에서이미지가 매우 느리게 감지 됨

- (void)findObject 
{ 
    //NSLog(@"%@ %@", self, NSStringFromSelector(_cmd)); 

    width = 0; 

    CvMemStorage* storage = cvCreateMemStorage(0); 
    static CvScalar colors[] = 
    { 
     {{0,0,255}}, 
     {{0,128,255}}, 
     {{0,255,255}}, 
     {{0,255,0}}, 
     {{255,128,0}}, 
     {{255,255,0}}, 
     {{255,0,0}}, 
     {{255,0,255}}, 
     {{255,255,255}} 
    }; 

    if(!objectToFind || !image) 
    { 
     NSLog(@"Missing object or image"); 
     return; 
    } 

    CvSize objSize = cvGetSize(objectToFind); 
    IplImage* object_color = cvCreateImage(objSize, 8, 3); 
    cvCvtColor(objectToFind, object_color, CV_GRAY2BGR); 

    CvSeq *objectKeypoints = 0, *objectDescriptors = 0; 
    CvSeq *imageKeypoints = 0, *imageDescriptors = 0; 
    int i; 
    CvSURFParams params = cvSURFParams(500, 1); 

    double tt = (double)cvGetTickCount(); 
    NSLog(@"Finding object descriptors"); 
    cvExtractSURF(objectToFind, 0, &objectKeypoints, &objectDescriptors, storage, params); 

    NSLog(@"Object Descriptors: %d", objectDescriptors->total); 
    cvExtractSURF(image, 0, &imageKeypoints, &imageDescriptors, storage, params); 

    NSLog(@"Image Descriptors: %d", imageDescriptors->total); 
    tt = (double)cvGetTickCount() - tt; 

    NSLog(@"Extraction time = %gms", tt/(cvGetTickFrequency()*1000.)); 
    CvPoint src_corners[4] = {{0,0}, {objectToFind->width,0}, {objectToFind->width, objectToFind->height}, {0, objectToFind->height}}; 
    CvPoint dst_corners[4]; 
    CvSize size = cvSize(image->width > objectToFind->width ? image->width : objectToFind->width, 
         objectToFind->height+image->height); 
    output = cvCreateImage(size, 8, 1); 
    cvSetImageROI(output, cvRect(0, 0, objectToFind->width, objectToFind->height)); 
    //cvCopy(objectToFind, output); 
    cvResetImageROI(output); 
    cvSetImageROI(output, cvRect(0, objectToFind->height, output->width, output->height)); 
    cvCopy(image, output); 
    cvResetImageROI(output); 

    NSLog(@"Locating Planar Object"); 
#ifdef USE_FLANN 
    NSLog(@"Using approximate nearest neighbor search"); 
#endif 
    if(locatePlanarObject(objectKeypoints, objectDescriptors, imageKeypoints, 
          imageDescriptors, src_corners, dst_corners)) 
    { 
     for(i = 0; i < 4; i++) 
     { 
      CvPoint r1 = dst_corners[i%4]; 
      CvPoint r2 = dst_corners[(i+1)%4]; 
      //cvLine(output, cvPoint(r1.x, r1.y+objectToFind->height), 
        //cvPoint(r2.x, r2.y+objectToFind->height), colors[6]); 
      cvLine(output, cvPoint(r1.x, r1.y+objectToFind->height), 
        cvPoint(r2.x, r2.y+objectToFind->height), colors[6],4); 
      //if(i==0) 
       width = sqrt(((r1.x-r2.x)*(r1.x-r2.x))+((r1.y-r2.y)*(r1.y-r2.y))); 
     } 
    } 
    vector<int> ptpairs; 
    NSLog(@"finding Pairs"); 
#ifdef USE_FLANN 
    flannFindPairs(objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs); 
#else 
    findPairs(objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs); 
#endif 
    /* for(i = 0; i < (int)ptpairs.size(); i += 2) 
    { 
     CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem(objectKeypoints, ptpairs[i]); 
     CvSURFPoint* r2 = (CvSURFPoint*)cvGetSeqElem(imageKeypoints, ptpairs[i+1]); 
     cvLine(output, cvPointFrom32f(r1->pt), 
       cvPoint(cvRound(r2->pt.x), cvRound(r2->pt.y+objectToFind->height)), colors[8]); 
    }*/ 

    float dist = 629.0/width; 
    [distanceLabel setText:[NSString stringWithFormat:@"%.2f",dist]]; 


    NSLog(@"Converting Output"); 
    UIImage *convertedOutput = [OpenCVUtilities UIImageFromGRAYIplImage:output]; 

    NSLog(@"Opening Stuff"); 
    [imageView setImage:convertedOutput]; 
    cvReleaseImage(&object_color); 

    [activityView stopAnimating]; 

} 

내 원래 이미지와 내가 감지 할 로고입니다.

제 질문에 명확하지 않은 점이 있으면 알려주십시오.

답변

1

프로파일 링을 사용하여 코드의 어느 부분이 가장 느린 지 결정해야합니다.

  1. 당신은 그가 왼쪽 상단에 "실행"버튼을 누른 채로 다음 "Profile (프로필)"을 선택합니다
    당신이 엑스 코드를 사용하고 있기 때문에, 당신은 내장 된 프로파일 손 부근에 있습니다.
  2. 프로필을 클릭하고 시간 프로필러를 선택하십시오.
  3. 프로파일 러에서 "중지"를 누른 후 "누락 된 심볼 숨기기", "시스템 라이브러리 숨기기"및 "주요 기능"을 선택하고 "스레드 별 분리"를 선택 해제하십시오.
  4. 이제 주 기능을 찾아보고 숨겨진 오른쪽 화살표가 있습니다. 해당 화살표를 클릭하면 시간을 퍼센트로 볼 수 있고 calltree로 통계를 호출 할 수 있습니다.

이렇게 시작하는 방법입니다. 만큼 당신이 할 수있는 새로운 이미지와 메모리 스토리지를 만드는

  • 피하십시오 :

    는 일반적으로 나는 다음과 같은 제안 프로파일 않고 있습니다. (일시적으로 사용할 이미지를 함수에 전달하고 나중에 다시 사용할 수 있도록 외부에 이미지를 보존 할 수 있습니다.)

  • 이미지의 주요 부분으로 이미지의 크기를 줄입니다.
  • 적은 기술자

엄지 손가락의 두 가지 규칙을 사용

프로파일 링은 종종 놀라운 결과를 얻을 수로, 프로파일 후 을 개선하기 위해 무엇을 결정해야
  • .
  • 잠재적 인 이득을 줄이기 위해 노력하는 것이 빠르면 빠를수록 좋습니다.
관련 문제