opencv 筆記01Core_Mat

Mat - 基本圖像容器

Mat A, C;                                 // 只創建信息頭部分
A = imread(argv[1], CV_LOAD_IMAGE_COLOR); // 這裏爲矩陣開闢內存
Mat B(A);                                 // 使用拷貝構造函數
C = A; 
以上代碼中的所有Mat對象最終都指向同一個也是唯一一個數據矩陣。雖然它們的信息頭不同,但通過任何一個對象所做的改變也會影響其它對象。實際上,不同的對象只是訪問相同數據的不同途徑而已。這裏還要提及一個比較棒的功能:你可以創建只引用部分數據的信息頭。比如想要創建一個感興趣區域( ROI ),你只需要創建包含邊界信息的信息頭:
Mat D (A, Rect(10, 10, 100, 100) ); // using a rectangle
Mat E = A(Range:all(), Range(1,3)); // using row and column boundaries

如果矩陣屬於多個 Mat 對象,那麼當不再需要它時誰來負責清理?簡單的回答是:最後一個使用它的對象
但某些時候你仍會想拷貝矩陣本身(不只是信息頭和矩陣指針),這時可以使用函數 clone() 或者 copyTo() 。
Mat F = A.clone();
Mat G;
A.copyTo(G);

總結一下,你需要記住的:
  • OpenCV函數中輸出圖像的內存分配是自動完成的(如果不特別指定的話)。
  • 使用OpenCV的C++接口時不需要考慮內存釋放問題。
  • 賦值運算符和拷貝構造函數( ctor )只拷貝信息頭。
  • 使用函數 clone() 或者 copyTo() 來拷貝一副圖像的矩陣。

存儲 方法


有很多的顏色系統,各有自身優勢:

  • RGB是最常見的,這是因爲人眼採用相似的工作機制,它也被顯示設備所採用。
  • HSV和HLS把顏色分解成色調、飽和度和亮度/明度。這是描述顏色更自然的方式,比如可以通過拋棄最後一個元素,使算法對輸入圖像的光照條件不敏感。
  • YCrCb在JPEG圖像格式中廣泛使用。
  • CIE L*a*b*是一種在感知上均勻的顏色空間,它適合用來度量兩個顏色之間的 距離 。

每個組成元素都有其自己的定義域,取決於其數據類型。如何存儲一個元素決定了我們在其定義域上能夠控制的精度。最小的數據類型是 char ,佔一個字節或者8位,可以是有符號型(0到255之間)或無符號型(-127到+127之間)。儘管使用三個 char 型元素已經可以表示1600萬種可能的顏色(使用RGB顏色空間),但若使用float(4字節,32位)或double(8字節,64位)則能給出更加精細的顏色分辨能力。但同時也要切記增加元素的尺寸也會增加了圖像所佔的內存空間。

顯式地創建一個 Mat 對象

Mat M(2,2, CV_8UC3, Scalar(0,0,255)); 
CV_[The number of bits per item][Signed or Unsigned][Type Prefix]C[The channel number]
比如 CV_8UC3 表示使用8位的 unsigned char 型,每個像素由三個元素組成三通道。
Scalar 是個short型vector。指定這個能夠使用指定的定製化值來初始化矩陣。

int sz[3] = {2,2,2}; 
Mat L(3,sz, CV_8UC(1), Scalar::all(0));
上面的例子演示瞭如何創建一個超過兩維的矩陣:指定維數,然後傳遞一個指向一個數組的指針,這個數組包含每個維度的尺寸;其餘的相同
  • 爲已存在IplImage指針創建信息頭:

    IplImage* img = cvLoadImage("greatwave.png", 1);
    Mat mtx(img); // convert IplImage* -> Mat
    
  • Create() function: 函數

        M.create(4,4, CV_8UC(2));
        cout << "M = "<< endl << " "  << M << endl << endl;
  • MATLAB形式的初始化方式: zeros()ones(), :eyes() 。使用以下方式指定尺寸和數據類型:

    Mat E = Mat::eye(4, 4, CV_64F);    
    
    Mat O = Mat::ones(2, 2, CV_32F);    

    Mat Z = Mat::zeros(3,3, CV_8UC1);

  • 對於小矩陣你可以用逗號分隔的初始化函數:

    Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0); 

格式化打印


  • 默認方式

        cout << "R (default) = " << endl <<        R           << endl << endl;
    
    Default Output
  • 以逗號分隔的數值 (CSV)

        cout << "R (csv)     = " << endl << format(R,"csv"   ) << endl << endl;
    
    Default Output
  • Numpy

        cout << "R (numpy)   = " << endl << format(R,"numpy" ) << endl << endl;
    
    Default Output
  • C語言

        cout << "R (c)       = " << endl << format(R,"C"     ) << endl << endl;
    
    Default Output

  • 2維點

        Point2f P(5, 1);
        cout << "Point (2D) = " << P << endl << endl;
    
    Default Output
  • 3維點

        Point3f P3f(2, 6, 7);
        cout << "Point (3D) = " << P3f << endl << endl;
    
    Default Output
  • 基於cv::Mat的std::vector

        vector<float> v;
        v.push_back( (float)CV_PI);   v.push_back(2);    v.push_back(3.01f);
        
        cout << "Vector of floats via Mat = " << Mat(v) << endl << endl;
    
    Default Output
  • std::vector點

        vector<Point2f> vPoints(20);
        for (size_t E = 0; E < vPoints.size(); ++E)
            vPoints[E] = Point2f((float)(E * 5), (float)(E % 7));
    
        cout << "A vector of 2D Points = " << vPoints << endl << endl;
    
    Default Output


發佈了23 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章