【问题标题】:Opencv C++ to C interface function conversionOpencv C++到C接口函数转换
【发布时间】:2013-04-23 15:10:58
【问题描述】:
void doCorrectIntensityVariation(Mat& image)
{   
    Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(19,19));
    Mat closed;
    morphologyEx(image, closed, MORPH_CLOSE, kernel);
    image.convertTo(image, CV_32F); // divide requires floating-point
    divide(image, closed, image, 1, CV_32F);
    normalize(image, image, 0, 255, NORM_MINMAX);
    image.convertTo(image, CV_8UC1); // convert back to unsigned int

}

inline void correctIntensityVariation(IplImage *img)
{
//Mat imgMat(img); copy the img
Mat imgMat;
imgMat = img; //no copy is done, imgMat is a header of img
doCorrectIntensityVariation(imgMat);
imshow("gamma corrected",imgMat); cvWaitKey(0);
}

当我打电话时

cvShowImage ("normal", n_im); cvWaitKey (0);
correctIntensityVariation(n_im);//here n_im is IplImage*
cvShowImage ("After processed", n_im); cvWaitKey (0);
// here I require n_im for further processing

我希望“处理后”与“伽马校正”相同,但我发现“处理后”与“伽马校正”不同,但与“正常”相同。为什么??出了什么问题??

【问题讨论】:

    标签: c++ c function opencv


    【解决方案1】:

    一个非常简单的包装器应该可以完成这项工作

    Cheetsheet of openCV

    我很少使用旧的 api,因为 Mat 更容易处理,而且 与旧的 c api 相比,它们没有性能损失。就像 openCV 教程页面说 C++ 接口的主要缺点是目前许多嵌入式开发系统仅支持 C。因此,除非您针对嵌入式平台,否则使用旧方法没有意义(除非您是受虐狂程序员,你在自找麻烦)。

    openCV tutorial

    cv::Mat 到 Ipl

    Ipl 到 cv::Mat 和 Mat 到 Ipl

    IplImage* pImg = cvLoadImage(“lena.jpg”);
    cv::Mat img(pImg,0); //transform Ipl to Mat, 0 means do not copy 
    IplImage qImg; //not pointer, it is impossible to overload the operator of raw pointer
    qImg = IplImage(img); //transform Mat to Ipl
    

    编辑:我之前犯了一个错误,如果 Mat 会在函数中重新分配,你需要 复制或尝试从 Mat 中窃取资源(我还不知道该怎么做)。

    复制数据

    void doCorrectIntensityVariation(cv::Mat& image)
    {
        cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(19,19));
        cv::Mat closed;
        cv::morphologyEx(image, closed, cv::MORPH_CLOSE, kernel);
        image.convertTo(image, CV_32F); // divide requires floating-point
        cv::divide(image, closed, image, 1, CV_32F);
        cv::normalize(image, image, 0, 255, cv::NORM_MINMAX);
        image.convertTo(image, CV_8UC1); // convert back to unsigned int
    
    }
    
    //don't need to change the name of the function, the compiler treat
    //these as different function in c++
    void doCorrectIntensityVariation(IplImage **img)
    {
        cv::Mat imgMat;
        imgMat = *img; //no copy is done, imgMat is a header of img
        doCorrectIntensityVariation(imgMat);
    
        IplImage* old = *img;
        IplImage src = imgMat;
        *img = cvCloneImage(&src);
        cvReleaseImage(&old);
    }
    
    int main()
    {
    
    
        std::string const name = "onebit_31.png";
        cv::Mat mat = cv::imread(name);
        if(mat.data){
            doCorrectIntensityVariation(mat);
    
            cv::imshow("gamma corrected mat",mat);
            cv::waitKey();
        }
    
        IplImage* templat = cvLoadImage(name.c_str(), 1);
        if(templat){
            doCorrectIntensityVariation(&templat);
            cvShowImage("mainWin", templat);
    
            // wait for a key
            cvWaitKey(0);
            cvReleaseImage(&templat);
        }
    
    
    
        return 0;
    }
    

    你可以写一个小函数来减轻琐事

    void copy_mat_Ipl(cv::Mat const &src, IplImage **dst)
    {
             IplImage* old = *dst;
            IplImage temp_src = src;
            *dst = cvCloneImage(&temp_src);
            cvReleaseImage(&old);
    }
    

    并在函数中调用它

    void doCorrectIntensityVariation(IplImage **img)
    {
        cv::Mat imgMat;
        imgMat = *img; //no copy is done, imgMat is a header of img
        doCorrectIntensityVariation(imgMat);    
        copy_mat_to_Ipl(imgMat, img);
    }
    

    我将发布如何从 Mat 中“窃取”资源,而不是在之后复制 我想出了一个可靠的解决方案。有人知道怎么做吗?

    【讨论】:

    • 其实我想输出IplImage*,可以吗?因为我的整个源需要 IplImage* 作为输入而不是 Mat 并返回 IplImage* 作为输出而不是 doCorrectIntensityVariation。
    • 我不能使用 img=imgMat;返回图片;在内联 IplImage* doCorrectIntensityVariation(IplImage* img) 中。它说不能在分配中将'cv :: Mat'转换为'IplImage * {aka _IplImage *}'
    • 行后 imgMat = img; imgMat 充当 img 的别名,换句话说,任何适用于 imgMat 的内容也适用于 img。您可以将您的 IplImage*(在本例中为 img)传递到包装器中,它将是您要求的输出.我编辑了我的答案,你可以再检查一遍
    • 我不明白。你的意思是IplImage* pImg = cvLoadImage(“lena.jpg”); cv::Mat img(pImg,0); //将Ipl转换为Mat,0表示不复制IplImage qImg; //不是指针,不可能重载原始指针的运算符 qImg = IplImage(img); doCorrectIntensityVariation(&qImg);
    • 最终我需要 IplImage* 作为输出而不是 IplImage* 以便我可以将其用于进一步处理......有什么想法吗??
    猜你喜欢
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 2015-06-27
    相关资源
    最近更新 更多