程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> OpenCV 矩陣:圖像的基本

OpenCV 矩陣:圖像的基本

編輯:關於C++

我們有很多方式可以從現實生活中得到圖片,數碼相機,掃描儀,或者我們幾乎人手有一部的手機。然而,當生活中的圖在數字設備上存儲的時候,一幅圖片被分成了很多很多的像素點,像素點就像拼圖的時候的碎片,一個個碎片來構成一副圖。而每個像素點都是由一個0-255的數字值來表示。在openCV中,一個圖片被很多像素點表示,這些表示像素點的值構成了一個矩陣。

上面的圖中,由表示像素點的值構成了矩陣,在openCV中,Mat(矩陣)是表示圖片的基本。

Mat由兩部分組成,一個是matrixheader,裡面存儲了一些信息,比如矩陣的大小,矩陣的存儲地址等;另外一個是矩陣,裡面包含了圖片的每一個像素值。

明白了Mat有兩部分組成後,能夠更好的理解Mat的賦值。看下面的一段代碼

#include<iostream>  
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
       
using namespace cv;  
       
int main()  
{  
    Mat A, C;                                // 聲明其實只是創建了header部分  
    A = imread("zh.png",CV_LOAD_IMAGE_COLOR); // 這裡,A的matrix部分指向了一個矩陣  
       
    Mat B(A);                                // 使用構造方法賦值,其實只有header部分復制了,  
                                                //但是matrix復制的是地址空間,指向的是同一片區域  
       
    C = A;                                    // 同理,header部分復制了,但是matrix指向同一片區域  
    //A = A * 0;  //只是改變了A,但是三幅圖都變了  
    imshow("A", A); //顯示的三幅圖片都是同一片區域  
    imshow("B", B);  
    imshow("C", C);  
    waitKey();  
    return 0;  
}

上面的A,B,C的header只是值相同,但是每一個Mat都有自己的header,但是matrix不一樣,他們不僅僅值相同,並且指向相同的地址空間。

現在你可能會疑惑,如果三個Mat的matrix都是同一片地址空間,那麼當它不再需要的時候,由誰來清除它。其實由最後一個使用它的那個Mat來清除,這裡面涉及的引用計數問題,和C++的引用計數應該是相似的。

如果我們需要一個和原來矩陣值一樣,但是原來Mat的改變不會影響新的Mat。解決這個,openCV提供了clone() 和copyTo() 這兩個函數。

Mat F = A.clone();  
Mat G;  
A. copyTo(G);

上面的G和F,現在的值和A一樣,但是A的改變不會影響到他們。

存儲的方式:

就是如何存儲像素值,最簡單的方式是用灰度矩陣來存儲,前提是我們的圖片是黑白的時候,當然還有一些其它的圖片存儲方式,比如常見的RGB。

顯示的創建Mat:

可以使用imwrite()將圖片寫出,也可以使用<<操作符。看下面的一段程序

Mat M(2, 2, CV_8UC3, Scalar(0, 0, 255));  
std::cout << "M = " << std::endl<<""<< M << std::endl << std::endl;  
system("pause");//讓程序不閃退

Mat的構造函數,前兩個參數(這裡都是2)指定Mat的大小,行與列數。

定義“CV_8UC3”的格式一般是這樣的

CV_[The number of bits per item][Signed orUnsigned][Type Prefix]C[The channel number]

例如,CV_8UC3意思是我們用8 bitunsigned值表示單個數值,每個像素有3個數值來形成3個channel。

使用create()函數創建。    

Mat M;  
M.create(4, 4, CV_8UC(2)); //參數的含義前面已經介紹了  
cout << "M = " << endl<< ""<< M << endl << endl;

返回欄目頁:http://www.bianceng.cn/Programming/cplus/

Matlab風格,使用zeros(),ones(),eye(),

Mat E = Mat::eye(4, 4, CV_64F);  
cout << "E = " << endl<<""<< E << endl << endl;  
      
Mat O = Mat::ones(2, 2, CV_32F);  
cout << "O = " << endl<<""<< O << endl << endl;  
      
Mat Z = Mat::zeros(3, 3, CV_8UC1);  
cout << "Z = " << endl<< ""<< Z << endl << endl;

小矩陣,可以用這種方式初始化:

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

cout << "C = " << endl<< ""<< C << endl << endl;

可以使用randu()函數,隨機化一個矩陣,需要給定一個隨機的上下界

Mat R = Mat(3, 2, CV_8UC3);  
randu(R, Scalar::all(0),Scalar::all(255)); //0至255的值  
cout << "R = " << endl<< ""<< R << endl << endl;

作者:csdn博客 鐘桓

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved