9

使用 OpenCv 2.4

我有两个加载图像的选项:

  1- CvMat and Imread

  2- IpImage and CvLoadImage    

哪个更好用?我尝试将两者混合并最终出现段错误。

4

4 回答 4

14

imread返回 a Mat,而不是CvMat。它们是两个不同的接口(Mat/imread用于 C++ 和 Ipl... 和 Cv.. 用于 C 接口)。

C++ 接口更好、更安全、更易于使用。它会自动为您处理内存,并允许您为同一任务编写更少的代码。OpenCV 家伙提倡使用 C++,除非某些非常具体的项目要求迫使您使用 C。

示例 (C++)

cv::Mat image = imread("path/to/myimage.jpg")
if(image.empty())
    return;

cv::imshow("Image", image);

cv::Mat bw = image > 128; // threshold image
cv::Mat crop = image(cv::Rect(0, 0, 100, 100)); // a 100px x 100px crop
crop= 0; // set image to 0

cv::waitKey();
// end code here

请注意,如果没有另外说明,所有矩阵分配都引用相同的数据。在上面的示例中,crop矩阵指向image,并将其设置为零会将 的特定部分设置image为 0。

要创建数据的新副本,请使用 Mat::copyTo 或 Mat::clone();

和C接口

IplImage* pImg = CvLoadImage("path/to/myimage.jpg");
if(pImg == NULL)
    return;

// ... big bloat to do the same operations with IplImage    

CvShowImage("Image", pImg);
cvWaitKey();
CvReleaseImage(&pImg); // Do not forget to release memory.
// end code here
于 2012-06-20T08:38:04.550 回答
0

IplImage 和 Mat 都是可相互转换的。

我建议你使用 Mat 和 imread(),因为从 Mat 中获取数据非常容易。

Mat::data 返回一个指向一维实际矩阵数据的指针,并且这些值很容易访问。http://opencv.itseez.com/modules/core/doc/old_basic_structures.html?highlight=mat#union%20data

如果您想在 OpenCV 中为各种跟踪算法(例如 OpenTLD)添加机器学习概念,您可以使用 Mat.data 轻松访问数据以获取指向实际矩阵的指针。

OpenCV 的许多实用程序(例如 CalcOpticalFlowPyrLK 等)都需要 Mat。我建议你使用Mat。IplImage 现在是老东西了。

于 2012-06-20T10:23:32.990 回答
0

这取决于您对指针的舒适程度。在 IplImage 中,您可以访问数据为

 data[i*widthstep+j*nchannels +k]

其中 i,j,k 是一些整数,这是非常简单的方法。在 3 维的普通矩阵中,访问数据并不容易。对于普通矩阵数据访问是针对 a[i][j]

  *(*(a + i) + j) is the value of jth element of ith row in matrix a
于 2012-06-20T11:09:35.390 回答
0

来自 OpenCV_2 食谱:

此结构继承自 IPL 库(即英特尔图像处理库),现在与 IPP 库(英特尔集成性能原语库)集成。如果您使用使用旧 C 接口创建的代码和库,则可能需要操作这些 IplImage 结构。幸运的是,有一种方便的方法可以将 IplImage 转换为 cv::Mat 对象。

IplImage* iplImage = cvLoadImage("c:\img.jpg"); cv::Mat image4(iplImage,false);

函数 cvLoadImage 是用于加载图像的 C 接口函数。cv::Mat 对象的构造函数中的第二个参数表示数据不会被复制(如果需要新的副本,请将其设置为 true,而 false 是默认值,因此可以省略),即两者IplImage 和 image4 将共享相同的图像数据。您需要注意不要创建悬空指针。为此,将 IplImage 指针封装到 OpenCV 2 提供的引用计数指针类中会更安全:

cv::Ptr iplImage = cvLoadImage("c:\img.jpg");

否则,如果需要释放 IplImage 结构指向的内存,则需要显式执行: cvReleaseImage(&iplImage); 请记住,您应该避免使用这种过时的数据结构。相反,始终使用 cv::Mat。

于 2015-07-08T23:03:48.527 回答