1. 程式人生 > >[OpenCV]OpenCV常用語法函式

[OpenCV]OpenCV常用語法函式

目錄

1. 載入影象(cv::imread)

imread()功能是載入影象檔案成為一個Mat物件,如果讀取檔案失敗,則會返回一個空矩陣,即 Mat::data 的值是 NULL。imread()函式的宣告如下:

Mat imread(const string& filename, int flags=1)

其中第一個引數是表示影象檔名稱;第二個引數表示載入的影象是什麼型別,支援常見的三個引數值:

  • IMREAD_UNCHANGED(<0)表示載入原圖,不做任何改變
  • IMREAD_GRAYSCALE(0)表示把原圖作為灰度影象載入進來
  • IMREAD_COLOR(>0)表示把原圖作為RGB影象載入進來

imread()函式支援多種檔案格式,且該函式是根據影象檔案的內容來確定檔案格式,而不是根據檔案的副檔名來確定。所只是的檔案格式如下:

  • Windows 點陣圖檔案 - BMP, DIB;
  • JPEG 檔案 - JPEG, JPG, JPE;
  • 行動式網路圖片 - PNG;
  • 行動式影象格式 - PBM,PGM,PPM;
  • Sun rasters - SR,RAS;
  • TIFF 檔案 - TIFF,TIF;
  • OpenEXR HDR 圖片 - EXR;
  • JPEG 2000 圖片- jp2。

你所安裝的 OpenCV 並不一定能支援上述所有格式,檔案格式的支援需要特定的庫,只有在編譯 OpenCV 添加了相應的檔案格式庫,才可支援其格式。

2. 顯示影象(cv::nameWindows與cv::imshow)

  • namewindows功能是建立一個OpenCV視窗,它是由OpenCV自動建立與釋放,你無須手動銷燬它。
  • 常見用法 nameWindows("windowTitle", WINDOW_AUTOSIZE)
  • WINDOW_AUTOSIZE 會自動根據影象大小,顯示視窗大小,不能認為改變視窗大小
  • WINDOW_NORMAL 跟QT整合的時候會使用,允許修改視窗大小
  • imshow 根據視窗名稱顯示影象到視窗上去,第一個引數是視窗名稱,第二個引數是Mat物件

3. 修改影象(cv::cvtColor)

cvtColor的功能是把影象從一個色彩空間轉換到另一個色彩空間。有三個引數如下:
第一個引數表示原影象
第二個引數表示色彩空間轉換之後的影象
第三個引數表示轉換方式,如:CV_BGR2GRAY、CV_BGR2HSV等
程式碼如下:

cvtColor(src, outputImage, CV_BGR2GRAY);

4. 儲存影象(cv::imwrite)

將影象寫入檔案,可使用 imwrite()函式,該函式的宣告如下:

bool imwrite( const string& filename, InputArray img, const vector<int>& params=vector<int>());

檔案的格式由 filename 引數指定的副檔名確定。推薦使用 PNG 檔案格式。BMP 格式是無損格式,但是一般不進行壓縮,檔案尺寸非常大;JPEG 格式的檔案嬌小,但是 JPEG 是有失真壓縮,會丟失一些資訊。PNG 是無失真壓縮格式,推薦使用。
imwrite()函式的第三個引數 params 可以指定檔案格式的一些細節資訊。這個引數裡面的數值是跟檔案格式相關的:

  • JPEG:表示影象的質量,取值範圍從 0 到 100。數值越大表示影象質量越高,當然檔案也越大。預設值是 95。
  • PNG:表示壓縮級別,取值範圍是從 0 到 9。數值越大表示檔案越小,但是壓縮花費的時間也越長。預設值是 3。
  • PPM,PGM 或 PBM:表示檔案是以二進位制還是純文字方式儲存,取值為0 或 1。如果取值為 1,則表示以二進位制方式儲存。預設值是 1。

並不是所有的 Mat 物件都可以存為影象檔案,目前支援的格式只有 8U 型別的單通道和 3 通道(顏色順序為 BGR)矩陣;如果需要要儲存 16U 格式影象,只能使用 PNG、JPEG 2000 和 TIFF 格式。如果希望將其他格式的矩陣儲存為影象檔案,可以先用 Mat::convertTo()函式或者 cvtColor()函式將矩陣轉為可以儲存的格式。
注意:在儲存檔案時,如果檔案已經存在,imwrite()函式不會進行 醒,將直接覆蓋掉以前的檔案。

5. 讀視訊

VideoCapture 既可以從視訊檔案讀取影象,也可以從攝像頭讀取影象。可以使用該類的建構函式開啟視訊檔案或者攝像頭。如果 VideoCapture 物件已經建立,也可以使用 VideoCapture::open()開啟,VideoCapture::open()函式會自動呼叫VideoCapture::release()函式,先釋放已經開啟的視訊,然後再開啟新視訊。

VideoCapture cap(0);  //開啟第一個攝像頭
VideoCapture cap("filename.avi");  //開啟視訊檔案

如果要讀一幀,可以使用 VideoCapture::read()函式。VideoCapture 類過載了>>操作符,實現了讀視訊幀的功能。

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(int argc, char** argv)
{
    VideoCapture cap(0);    //開啟第一個攝像頭
    if(!cap.isOpened()) {   //檢查是否成功開啟
        cerr << "Can not open a camera or file." << endl;
        return -1;
    }
    Mat edges;
    namedWindow("edges",1); //建立視窗
    while(1) {
        Mat frame;
        cap >> frame;  //從 cap 中讀一幀,存到 frame
        if(frame.empty()){  //如果未讀到影象
            break;
        }
        cvtColor(frame, edges, CV_BGR2GRAY);  //將讀到的影象轉為灰度圖
        Canny(edges, edges, 50, 150, 3);  //進行邊緣 取操作
        imshow("edges", edges);     //顯示結果
        if(waitKey(30) >= 0) {   //等待 30 秒,如果按鍵則推出迴圈
            break;
        }
    }
    //退出時會自動釋放 cap 中佔用資源
    return 0;
}

寫視訊
使用 OpenCV 建立視訊也非常簡單,與讀視訊不同的是,你需要在建立視訊時設定一系列引數,包括:檔名,編解碼器,幀率,寬度和高度等。編解碼器使用四個字元表示,可以是 CV_FOURCC('M','J','P','G')、CV_FOURCC('X','V','I','D')及CV_FOURCC('D','I','V','X')等。如果使用某種編解碼器無法建立視訊檔案,請嘗試其他的編解碼器。
將影象寫入視訊可以使用 VideoWriter::write()函式,VideoWriter 類中也過載了<<操作符,使用起來非常方便。另外需要注意:待寫入的影象尺寸必須與建立視訊時指定的尺寸一致。

#include <stdio.h>
#include <iostream>
#include "opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
    //定義視訊的寬度和高度
    Size s(320, 240);
    //建立 writer,並指定 FOURCC 及 FPS 等引數
    VideoWriter writer = VideoWriter("/Users/Longxia/Downloads/myvideo.avi", CV_FOURCC('M','J','P','G'), 25, s);
    //檢查是否成功建立
    if(!writer.isOpened()) {
        cerr << "Can not create video file.\n" << endl;
        return -1;
    }
    //視訊幀
    Mat frame(s, CV_8UC3);
    for(int i = 0; i < 100; i++)
    {
        //將影象置為黑色
        frame = Scalar::all(0);
        //將整數 i 轉為 i 字串型別
        char text[128];
        snprintf(text, sizeof(text), "%d", i);
        //將數字繪到畫面上
        putText(frame, text, Point(s.width/3, s.height/3),
                FONT_HERSHEY_SCRIPT_SIMPLEX, 3, Scalar(0,0,255), 3, 8);
        //將影象寫入視訊
        writer << frame;
    }
    //退出程式時會自動關閉視訊檔案
    return 0;
}```