SIFT-GPU关于SaveSIFT函数的改进

SIFT-GPU是一个高效的进行SIFT特征提取和匹配的工具,是目前我用过的速度最快的工具。网址如下:http://www.cs.unc.edu/~ccwu/siftgpu/#lowesift
我在用SIFT-GPU进行SIFT特征提取的过程中,发现运行的速度比较慢,通过对运行的代码的时间分析,发现主要元凶是保存SIFT特征的函数SaveSIFT占用了大量的时间(包括匹配的时间,save的时间大约在80%以上)。然后分析源码可以看出来它的源码是用C++的stream类进行保存的,我们都知道C语言的fprintf比前面的方法要快很多,因此我改进了其中的代码,是SiftGPU工程下的SiftPyramid.cpp文件中的SaveSIFT函数。
这里我只改了一部分,因为SaveSIFT是可以选择保存为二进制格式文件还是保存为普通的文件的,对于保存为二进制格式的部分我没有改动,有需要的请自己修改,改动的方法是相同的。调整后的代码运行速度大约是原有代码运行速度的10倍。
改进后的代码如下:

void SiftPyramid::SaveSIFT(const char * szFileName)
{
    if (_featureNum <=0) return;
    float * pk = &_keypoint_buffer[0];
    FILE *f = fopen(szFileName, "w");
    cout << szFileName << endl;
    if(GlobalUtil::_BinarySIFT)
    {
        std::ofstream out(szFileName, ios::binary);
        out.write((char* )(&_featureNum), sizeof(int));

        if(GlobalUtil::_DescriptorPPT)
        {
            int dim = 128;
            out.write((char* )(&dim), sizeof(int));
            float * pd = &_descriptor_buffer[0] ;
            for(int i = 0; i < _featureNum; i++, pk+=4, pd +=128)
            {
                out.write((char* )(pk +1), sizeof(float));
                out.write((char* )(pk), sizeof(float));
                out.write((char* )(pk+2), 2 * sizeof(float));
                out.write((char* )(pd), 128 * sizeof(float));
            }
        }else
        {
            int dim = 0;
            out.write((char* )(&dim), sizeof(int));
            for(int i = 0; i < _featureNum; i++, pk+=4)
            {
                out.write((char* )(pk +1), sizeof(float));
                out.write((char* )(pk), sizeof(float));
                out.write((char* )(pk+2), 2 * sizeof(float));
            }
        }
    }
    else
    {
        //std::ofstream out(szFileName);
        //out.flags(ios::fixed);

        if(GlobalUtil::_DescriptorPPT)
        {
            float * pd = &_descriptor_buffer[0] ;
            //out<<_featureNum<<" 128"<
            fprintf(f, "%d 128\n", _featureNum);
            for(int i = 0; i < _featureNum; i++)
            {
                //in y, x, scale, orientation order
                //out<
                //  <
                fprintf(f, "%.2f %.2f %.3f %.3f\n", pk[1], pk[0], pk[2], pk[3]);
                out << setprecision(12) << pk[1] <<  " " << pk[0] << " " << pk[2] << " " << pk[3] << endl;
                pk+=4;
                for(int k = 0; k < 128; k ++, pd++) 
                {
                    if (GlobalUtil::_NormalizedSIFT)
                    {
                        //out << ((unsigned int)floor(0.5 + 512.0f*(*pd))) << " ";
                        fprintf(f, "%u ", ((unsigned int)floor(0.5 + 512.0f*(*pd))));
                    }
                    else
                    {
                        //out << setprecision(8) << pd[0] << " ";
                        fprintf(f, "%.8f ", pd[0]);
                    }

                    if ((k + 1) % 20 == 0)// out<
                        fprintf(f, "\n");

                }
                //out<
                fprintf(f, "\n");
            }

        }else
        {
            //out<<_featureNum<<" 0"<
            fprintf(f, "%d 0", _featureNum);
            for(int i = 0; i < _featureNum; i++, pk+=4)
            {
                //out<
                fprintf(f,"%f %f %f %f\n", pk[1], pk[0], pk[2], pk[3]);
            }
        }
    }
    fclose(f);
}

你可能感兴趣的:(三维重建)