在设备中检测图像的速度非常慢

时间:2012-12-18 11:18:49

标签: objective-c ios xcode opencv surf

我正在使用此SURF代码来检测图像中的徽标。它工作正常,但速度很慢。关于如何优化它的任何想法?

- (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];

}

在上面的代码中,image是我的原始图片,objectToFind是我想要检测的徽标。

如果我的问题不明确,请告诉我。

1 个答案:

答案 0 :(得分:1)

您需要使用分析来确定代码的哪一部分是最慢的 由于您使用的是XCode,因此您可以使用内置的分析器:

  1. 在左上角,按住“运行”按钮并选择“个人资料”。
  2. 单击Profile并选择Time Profiler。
  3. 过了一会儿,你在分析器中按“停止”,然后选择“隐藏缺失的符号”,“隐藏系统库”和“顶部功能”,取消选择“按线程分离”。
  4. 现在查找功能主,后面有一个隐藏的右箭头。单击该箭头,您可以按百分比查看时间并通过calltree查看统计信息。
  5. 这就是你的开始。

    一般来说,我有以下建议没有分析

    • 尽可能避免创建新图像和内存存储。 (您可以将临时使用的图像传递给您的函数,并将这些图像保存在外部,以便以后可以重复使用。)
    • 缩小您的图片(和您的徽标),使其成为图片的主要部分
    • 使用较少的描述符

    两条经验法则:

    • 您需要决定在概要分析后要改进哪些,因为分析通常会产生令人惊讶的结果。
    • 你试图提高你获得的潜在收益的速度越快。