[OpenCV]OpenCV常用語法函式
目錄
- 1. 載入影象(cv::imread)
- 2. 顯示影象(cv::nameWindows與cv::imshow)
- 3. 修改影象(cv::cvtColor)
- 4. 儲存影象(cv::imwrite)
- 5. 讀視訊
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;
}```