Opencv c++到C接口函数的转换

Opencv C++ to C interface function conversion

本文关键字:函数 转换 接口 c++ Opencv      更新时间:2023-10-16
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

我希望"After processed"与"gamma corrected"相同,但我发现"After processed"与"gamma corrected"不相同,但与"normal"相同。为什么? ?出什么问题了?

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

openCV备忘单

我很少使用旧的api,因为Mat更容易处理与旧的c api相比,它们没有性能损失。比如openCVc++接口的主要缺点是目前许多嵌入式开发系统只支持C。因此,除非你的目标是嵌入式平台,否则使用旧方法是没有意义的(除非你是一个受虐狂程序员,你正在自找麻烦)。

openCV教程

cv::Mat to Ipl

Ipl to cv::Mat and Mat to 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那里"窃取"资源,而不是复制我算出了一个固溶体。有人知道怎么做吗?