在圖像處理中用Mat比IplImage 除了不用自己管理內存,Mat有其他的優勢沒?請熟悉OpenCV和圖像處理的大牛指點

剛剛開始接觸OpenCV和圖像處理,想做一個人臉識別,今天想用拉普拉斯運算元實現圖像的銳化,但是在網上只看到用Mat數據結構實現的,並沒有看到用IplImage實現的。而且,如果要把IplImage轉換成Mat時,函數是不能用的。求指點


IplImage是opencv較早版本用來表示圖像的結構體,在2.4之後的版本中出現了Mat,此結構體可以表示圖像、矩陣、向量等數據結構。相比IplImage,個人認為使用Mat的話opencv的許多特殊數據的定義,數據的輸出,函數使用比較方便。

真對lz提的「網上只看到mat數據結構實現的而沒有看到IplImage實現的,提供兩個解決方案:

1.必要時將自己的IplImage轉為Mat:

Mat img;

IplImage *src;

img = Mat(src);

src = IplImage(img);

2.直接用mat讀取圖片

Mat img = imread("xx.jpg");

先入為主,好多人最開始接觸opencv時高版本還沒出來iplimage是處理圖像的專有結構體,現在有了Mat表示圖像可能不太能接受,而且大多演算法IplImage也有對應函數介面。但還是建議用Mat吧,確實有好多方便之處。


沒必要再使用 IplImage,一點優勢都沒有。

珍愛生命,遠離需要手動釋放內存的 C 語言版本。

官方說了,很快 C 語言版本的函數都會被拋棄。

OpenCV will drop C API support soon

The C API is not developed for a long time. All the new stuff has the C++ API, and it is not backported to the C. So, C API becomes obsolete and causes pain in the neck, since it should be maintained. Thus, the decision is made to mark it as deprecated. But let me clarify the point:

  1. Actually C API will stay in the library, but it will not be available by default. It will be put into separate header files, that should be manually included by user. So, it would be possible to compile the legacy code, but you should add these compatibility includes manually.
  2. It is possible that OpenCV will generate compiler warnings in case you"re using C API. These warnings will notify you that you"re using deprecated API, and you should migrate to C++.
  3. At the same time in the long term C API may return to the OpenCV, so it can be used from the C code (e.g. low-level or embedded programming). But the plan is to autogenerate C wrappers for C++ code, as we do for Java and Python. This way C API will be always up-to-date, since it is generated from the C++ headers automatically. But this is a long-term dream, not for OpenCV 3.0, and if you want to work on that, please let us know (CONTRIBUTE | OpenCV).

話說回來,你實在想轉換格式也是可以的,摘抄自 opencv_cheatsheet.pdf

以下是不進行內存拷貝的方式(Shallow Copy),Mat 與其他數據結構共享真實的數據。

Mat image_alias = image;
float* Idata = new float[480*640*3];
Mat I(480, 640, CV_32FC3, Idata);

vector& iptvec(10);
Mat iP(iptvec); // iP 是 10x1 的 CV_32SC2 matrix

IplImage* oldC0 = cvCreateImage(cvSize(320,240),16,1);
Mat newC = cvarrToMat(oldC0);
IplImage oldC1 = newC;
CvMat oldC2 = newC;

以下是進行內存拷貝的方式(Deep Copy)。

Mat newC2 = cvarrToMat(oldC0).clone();
vector& ptvec = Mat_&(iP);


我先說下我喜歡用的是IplImage,而不是Mat。為什麼呢?因為IplImage可以自己管理內存,分配釋放都是要自己管理,條理性很清楚。不用Mat的原因是因為OCV已經把部分內存分配的任務給你做了,相比IplImage確實比較方便,相同的操作IplImage需要4行的代碼,Mat只需要1行就能解決了。說Mat不需要自己管理內存這是不對的,如果不需要管理內存,那麼ReleaseMat函數用來幹嘛的?還有一個,IplImage轉Mat可以直接用賦值語句操作,但是兩者是共享相同的內存圖像數據的,這個時候還敢說不用自己釋放內存么?

可能是本人經常使用IplImage的緣故,已經很熟練了,所以個人建議還是先熟練IplImage的使用,能做到內存的收放自如,再去用Mat很多函數就容易理解了。

純屬個人見解,僅供參考!


這個問題我在csdn的博客上面寫過,複製粘貼過來。。。

1.opencv中,幾種常見的圖像類型有:

IplImage,Mat,CvMat,CvArr

CvArr :

老版本的結構了。是一個抽象基類,在函數原型中,常見到CvArr(CvArr*),這就允許吧CvMar* 或者IplImage* 傳遞到程序或函數參數中了。

CvMat :

矩陣結構,

IplImage :

是較老版本的一種類型了,對圖像進行」編碼「的基本結構。這些圖像可能是灰度,彩色,4通道的(RGB+ alpha),其中,每個通道可以包含任意的整數或浮點數。

Mat:

新版本中的強大的一個圖像容器,是和Matlab中的函數對應的。基本上講 Mat 是一個類,由兩個數據部分組成:矩陣頭(包含矩陣尺寸,存儲方法,存儲地址等信息)和一個指向存儲所有像素值的矩陣(根據所選存儲方法的不同矩陣可以是不同的維數)的指針。矩陣頭的尺寸是常數值,但矩陣本身的尺寸會依圖像的不同而不同,通常比矩陣頭的尺寸大數個數量級。

2 opencv中存儲圖像類型轉換

(1)將IplImage類型轉換到Mat類型

Mat::Mat(const IplImage* img, bool copyData=false);

默認情況下,新的Mat類型與原來的IplImage類型共享圖像數據,轉換隻是創建一個Mat矩陣頭。當將參數copyData設為true後,就會複製整個圖像數據。

例:

IplImage*iplImg = cvLoadImage("greatwave.jpg", 1);

Matmtx(iplImg); // IplImage* -&>Mat 共享數據

// or : Mat mtx = iplImg;

(2)將Mat類型轉換到IplImage類型

同樣只是創建圖像頭,而沒有複製數據。

例:

IplImage ipl_img = img; // Mat -&> IplImage

(3)將CvMat類型轉換為Mat類型

與IplImage的轉換類似,可以選擇是否複製數據。

Mat::Mat(const CvMat* m, bool copyData=false);

(4)將Mat類型轉換為CvMat類型

與IplImage的轉換類似,不複製數據,只創建矩陣頭。

例:

// 假設Mat類型的imgMat圖像數據存在

CvMat cvMat = imgMat; // Mat -&> CvMat


建議使用新版的,因為新版的不用進行複雜的內存管理,而且語法上與matlab較為類似,可讀性也很強。


Mat支持C++模版庫中的演算法與符號重載,比基於C的IpIImage要靈活的多。最簡單的,你用cout直接就能把數據顯示出來,IpIImage能行?


Mat是c++實現的,新版;IplImage 是c實現的,舊版。就像 cpp的 vector 容器,跟c的手工管理數組。一個是面向對象,對象維護信息,泛型編程,支持各種操作重載;一個是面向過程,程序員管理信息,燒腦。

最新版 3.3 , Mat是主流。


Mat支持動態改變矩陣長度,用起來不要太爽,很多時候都需要支持這個


Mat 與 IplImage之間的轉換我都是用memcpy來進行內存數據的複製幾乎不用網上提供的那些方法,覺得或多或少會有問題


推薦閱讀:

opencv和pcl的區別?
OpenCV 與 OpenGL 的關係是什麼?
如何學習C++圖像處理?
ocr中文,字元切分時如何保證切出整個漢字,例如知這個字?
如何從0學習opencv,完成類似人臉檢測的畢設?

TAG:圖像處理 | OpenCV |