SURF特征点检测(带源代码以及IplImage和Mat类图像转换详细过程、cvmat/mat/IplImage之间深拷贝和浅拷贝)

时间:2020-12-14 08:58:34
SURF特征是类似于一种尺度不变的特征点,他的优点就是比SIFT效率高    
 //实现IplImage转换成mat     
     IplImage *img_1 = cvLoadImage("res\\me.jpg",1);
    cv::Mat image(img_1);
    if (image.empty())
    {
        fprintf(stderr,"cannot not load");
    }
//    cv::namedWindow("Original Image");
//    cv::imshow("Original Image", image);

//            vector是C++标准模版库中的部分内容,存放各种类型的对象
//              我们在使用opencv相关函数调用时候,会出现一种vector析构,造成程序莫名崩溃
//             只需要在opencv调用之前给vector分配内存即可解决,下面检测image中的SUFR特征点存储到keypoints中

    std::vector<cv::KeyPoint>keypoints;
    keypoints.resize(10000);//分配内存
    cv::SurfFeatureDetector surf(2500);
    cv::Mat featureImage;
    surf.detect(image,keypoints);
    cv::drawKeypoints(image,                    //源图像
        keypoints,                        //源图像的特征点
        featureImage,                      //目标图像
        cv::Scalar(255,255,255),               //匹配的颜色
        cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);  // 对每个特征点周围circle包含特征点大小和方向
//    cv::namedWindow("SURF Features");
//    cv::imshow("SURF Features",featureImage);
//一般IplImage与mat类都有自己的成员函数实现相互转换
/*
  深拷贝:单独分配空间,两者相互独立
  浅拷贝:不复制数据只创建矩阵头,数据共享所以你单独调用函数转换,会造成你后期使用不了这个图像相关数据
 1.cvMat(是opencv中重要的矩阵变换函数,一个cvmat的元素不一定是一个单一的数字,在矩阵中可以通过单一的输入来表示多值,这样实现三原色图像上面会多重色彩通道)
  Cvmat之间复制:Cvmat *a;CvMat *b=cvCloneMat(a);
 2.Mat之间复制:浅拷贝   Mat a;Mat b=a; Mat c(a);后期使用不太不好,不建议使用
           深拷贝   Mat a;Mat b=a.clone(a);Mat c;a.copyTo(c);第一个a到b,第二个a到c
 3.CvMat转成Mat:
//使用Mat的构造函数:Mat::Mat(const CvMat* m, bool copyData=false);    
 默认情况下copyData为false
 CvMat* a;
//注意:以下三种效果一致,均为浅拷贝
 Mat b(a);    //a "copy" to b
 Mat b(a, false);    //a "copy" to b
 Mat b = a;    //a "copy" to b
//注意:当将参数copyData设为true后,则为深拷贝(复制整个图像数据)
 Mat b = Mat(a, true); //a copy to b 
 4.Mat转CvMat:
//注意:浅拷贝
 Mat a;
 CvMat b = a; //a "copy" to b
//注意:深拷贝
 Mat a;
 CvMat *b;
 CvMat temp = a; //转化为CvMat类型,而不是复制数据
 cvCopy(&temp, b); //真正复制数据 cvCopy使用前要先开辟内存空间
 5.IplImage转Mat
//使用Mat的构造函数:Mat::Mat(const IplImage* img, bool copyData=false);    
 默认情况下copyData为false
 IplImage* srge("Lena.jpg");
//注意:以下三种效果一致,均为浅拷贝
 Mat M(srcImg);
 Mat M(srcImg, false);
 Mat M = srcImg;
  //注意:当将参数copyData设为true后,则为深拷贝(复制整个图像数据)
 Mat M(srcImg, true);
 6.Mat转IplImage
 //注意:浅拷贝 - 同样只是创建图像头,而没有复制数据
 Mat M;
 IplImage img = M;
 IplImage img = IplImage(M);
 //深拷贝
 cv::Mat img2;
 IplImage imgTmp = img2;
 IplImage *input = cvCloneImage(&imgTmp);
 7.IplImage转CvMat
//法一:cvGetMat函数
 IplImage* img;
 CvMat temp;
 CvMat* mat = cvGetMat(img, &temp);    //深拷贝
//法二:cvConvert函数
 CvMat *mat = cvCreateMat(img->height, img->width, CV_64FC3);    
//注意height和width的顺序
 cvConvert(img, mat);    //深拷贝
 8.CvMat转IplImage  
//法一:cvGetImage函数
 CvMat M;
 IplImage* img = cvCreateImageHeader(M.size(), M.depth(), M.channels());
 cvGetImage(&M, img);    //深拷贝:函数返回img
//也可写成
 CvMat M;
 IplImage* img = cvGetImage(&M, cvCreateImageHeader(M.size(), M.depth(),  M.channels()));
//法二:cvConvert函数
 CvMat M;
 IplImage* img = cvCreateImage(M.size(), M.depth(), M.channels());
 cvConvert(&M, img);    //深拷贝
*/
    IplImage img_2 = featureImage;
    IplImage *input = cvCloneImage(&img_2);
    CDC *pDC = GetDlgItem(IDC_SURF_Picture_1)->GetDC();
    CDC *pDC_2 = GetDlgItem(IDC_SURF_Picture_2)->GetDC();
    HDC hdc = pDC->GetSafeHdc();
    HDC hdc_2 = pDC_2->GetSafeHdc();
    CRect rect;
    CRect rect_2;
    GetDlgItem(IDC_SURF_Picture_1)->GetClientRect(&rect);
    GetDlgItem(IDC_SURF_Picture_2)->GetClientRect(&rect_2);
    CvvImage cimg,cimg_2;
    cimg.CopyOf(img_1,img_1->nChannels);
    cimg_2.CopyOf(input,input->nChannels);
    cimg.DrawToHDC(hdc,&rect);
    cimg_2.DrawToHDC(hdc_2,&rect_2);
    ReleaseDC(pDC);
    ReleaseDC(pDC_2);
    cimg.Destroy();
    cimg_2.Destroy();
SURF特征点检测(带源代码以及IplImage和Mat类图像转换详细过程、cvmat/mat/IplImage之间深拷贝和浅拷贝)
  SURF特征点检测(带源代码以及IplImage和Mat类图像转换详细过程、cvmat/mat/IplImage之间深拷贝和浅拷贝)
参照http://blog.csdn.net/zr459927180/article/details/50954791(仅供学习)