学 OpenCV 时总会撞见两套图像结构:老的 IplImage 和新的 cv::Mat。2015 年前后教材还在大量用 IplImage;今天结论已经很明确:新代码用 Mat

简史

对比

维度 IplImage Mat
语言风格 C C++
内存 手动 自动(引用计数)
新功能 基本冻结 持续更新
示例代码 老书/老博客 官方新文档
安全性 易泄漏/悬挂 仍可能误用,但轻松很多

转换

IplImage* ipl = ...;
cv::Mat m = cv::cvarrToMat(ipl); // 共享数据,注意生命周期

// 深拷贝:
cv::Mat m2 = cv::cvarrToMat(ipl).clone();

反过来(仅维护老接口时):

IplImage ipl = cvIplImage(mat); // 视 OpenCV 版本 API 略有差异

注意:共享数据时,不要先 release 源再用目标

迁移建议

  1. 新项目直接 Mat + VideoCapture + imshow
  2. 维护老项目时,在边界 cvarrToMat,内部别继续扩散 IplImage
  3. OpenCvSharp 用户使用与 Mat 对应的类型,避免 IplImage 封装

小结

「有的方法只有 IplImage 才有」在早期部分成立,现在几乎不成立。把 IplImage 当作历史兼容层即可;默认 Mat

现代代码骨架

#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    Mat img = imread("a.jpg");
    if (img.empty()) return 1;
    Mat gray;
    cvtColor(img, gray, COLOR_BGR2GRAY);
    imshow("g", gray);
    waitKey(0);
    return 0;
}

全程无需 IplImage。若链接老插件返回 IplImage*,在边界 cvarrToMat 一次,内部仍用 Mat

OpenCV 4 文档与示例均以 Mat 为准;继续学 IplImage 性价比低。