0

我是根据论文计算视觉图像,然后优化我的焦距、旋转和平移参数。出于这个原因,我通过移动所有像素 bw 真实图像和虚拟图像来创建成本函数。在我的 ceres 成本函数中,我基本上从标准化的真实图像中减去了标准化的虚拟图像。虚拟图像在评估回调函数中计算,成本在成本函数函数中计算。问题源于成本函子。优化在第一次迭代时终止,因为梯度等于 0。我使用 ceres::Central 进行梯度计算,但每次迭代只调用一次虚拟图像创建函数。但是,我需要分别为 f(x+h) 和 f(xh) 调用该函子。当我通过 9 个邻居计算归一化实像和归一化虚像时,我会继续迭代,但每次迭代需要 25 秒,这对我的情况来说是不可接受的。我需要这个evaluation_callback 函数,但我无法让它工作。

我查看了evaluation_callbacks 定义。上面写着“注意:评估回调与内部迭代不兼容。”

struct RcpAndFpOptimizer {
    RcpAndFpOptimizer(cv::Mat &V,  const cv::Mat I, int i,int j,double width, double height) : V_(V), I_(I), i_(i),
                               j_(j), width_(width), height_(height){}
    bool operator()(const double* const fp, const double* const rotation, const double* const translation, double* residuals) const {


       double intensity = V_.at<double>(j_, i_);



        double tmp = (double)I_.at<double>(j_,i_)-(double)intensity;
        residuals[0] = tmp;
        //std::cout<<"pixels(i,j): "<<i_<<" "<<j_<<" residual: "<<residuals[0]<<std::endl;
        return true;
    }

    const cv::Mat S_;
    cv::Mat& V_;
    const cv::Mat I_;
    const int i_,j_;
    double width_, height_;
};


virtual void PrepareForEvaluation(bool evaluateJacobians, bool newEvaluationPoint)
    {
        if(evaluateJacobians){
            std::cout<<"evaluation jacobian is called"<<std::endl;
        }
        if (newEvaluationPoint)
        {
            // do your stuff here, e.g. calculate integral image

            //Mat V(height_, width_, CV_8UC1);

            std::cout<<"preperation is called"<<std::endl;


            Intrinsic<double> intrinsicC = INTRINSIC_CAMERA;
            Intrinsic<double> intrinsicP= {(double)fP_[0],(double)fP_[0], double(width_/2), double(height_/2), 0, 0};

            //Convertion of array to  point3d
            Point3d bDist = Point3d(translation_[0],translation_[1], translation_[2]);

            //Convertion euler array to rotation matrix
            const Mat eulerAngles = (cv::Mat_<double>(3,1) << rotArray_[0], rotArray_[1], rotArray_[2]);

            Mat rotM = rcpFinder::euler2rot(eulerAngles);

            Mat tempVImg(height_, width_, CV_8UC1);

            for (int i = 0; i < width_; ++i) {
                for (int j = 0; j < height_ ; ++j) {
                    //std::cout<<"Virtual current x and y pixels: "<<i<<" "<<j<<std::endl;
                    Point3d unprojPRay = rcpFinder::unprojectPoints(Point2i(i,j),intrinsicC);

                    //Assigning the intensity from images
                    tempVImg.at<uchar>(j, i)= rcpFinder::genVirtualImg(S_, intrinsicP, bDist, unprojPRay,
                                                            planeNormalAndDistance_,  rotM);

                    auto pixelIntensity = tempVImg.at<uchar>(Point(j, i));
                    //std::cout<<"pixel intensity "<< pixelIntensity<<std::endl;

                }

            }

            //imshow("Virtual", tempVImg);
            Mat integralV;
            cv::integral(tempVImg, integralV);

            //std::cout<<"integral image type is "<<integralV.type()<<std::endl;

            rcpFinder::normalizePixelsImg(tempVImg, integralV, V_);





            /*imshow("Normalized Img", V_);
            waitKey(0);*/

        }
    }

    // stuff here
    const cv::Mat S_;
    cv::Mat& V_;
    int width_, height_;
    map<int, vector<Point3d>> planeNormalAndDistance_;
    double *translation_;
    double* rotArray_;
    double* fP_;

};

//调用仿函数如下

cv::Mat integralImgI;
    cv::integral(im1, integralImgI);
    cv::Mat normalizedRealImg;
    rcpFinder::normalizePixelsImg(im1, integralImgI, normalizedRealImg);

    Mat normalizedVirtualImg;

    //ceres::CostFunction* total_cost_function = 0;
    for (int i = 1; i < width-1; ++i) {
        for (int j = 1; j < height-1 ; ++j) {
            ceres::CostFunction* cost_function =
                    new ceres::NumericDiffCostFunction<RcpAndFpOptimizer, ceres::CENTRAL, 1, 1, 3, 3>(
                            new RcpAndFpOptimizer(normalizedVirtualImg, normalizedRealImg, i, j, width, height));

            problem.AddResidualBlock(cost_function, NULL, fp, rotationArray, translation);

        }
    }

    ceres::Solver::Options options;
    options.minimizer_progress_to_stdout = true;
    options.max_num_iterations = 50;
    options.update_state_every_iteration = true;



    options.evaluation_callback = (new evaluation_callback_functor(S, normalizedVirtualImg,width, height,
            mapNormalAndDist, translation,rotationArray, fp));

    ceres::Solver::Summary summary;
    ceres::Solve(options, &problem, &summary);

    std::cout << summary.BriefReport() << "\n";

我希望 ceres 求解器至少运行一次以上的迭代,梯度应该从一些值开始,并且必须通过迭代递减。

我用 9 个邻居对 pizels 进行了标准化。我发现当前的解决方案在成本函子中仅计算 9 个像素的虚拟图像并将它们用于一个像素归一化,但这太慢了。我有 640x480 像素和每个像素的 9 次计算。加上 NumericalCOstFunction 中的雅可比和梯度计算太多了。这就是为什么我想在evaluation_callback 函子中计算虚拟图像并在该函数内部对其进行归一化,并在成本函子中使用归一化图像。谢谢您的帮助。

4

1 回答 1

0

您不能使用内部迭代调用评估回调

https://groups.google.com/forum/#!topic/ceres-solver/zjQLIaSuAdQ

于 2019-06-05T04:04:27.443 回答