日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenCV可移植图形工具HighGUI实现图像和视频操作

發布時間:2024/7/23 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV可移植图形工具HighGUI实现图像和视频操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

OpenCV把用于操作系統、文件系統以及攝像機等硬件設備交換的函數納入了HighGUI(High-level Graphical User Interface)模塊中。有了HighGUI模塊,我們可以方便地打開窗口、顯示圖像、讀出或寫入圖像相關的文件、鼠標事件和鍵盤事件。下面將對三部分分別進行介紹。

HighGUI三部分的作用部分作用
硬件部分最主要是對攝像機的操作
文件系統部分主要工作是完成圖片的載入和保存
窗口系統GUI創建窗口并將圖片放入窗口顯示,同時添加響應鼠標和鍵盤事件功能

圖像文件的處理

圖像的載入與保存

使用cv::imread()讀取圖片

cv::Mat cv::imread(const string& filename, int flags=cv::IMREAD_COLOR)

作用:載入圖像,若失敗不會拋出異常,返回的是空的cv::Mat(可以用cv::Mat::empty()==true來判斷)。

flags的取值標志含義默認值
cv::IMREAD_COLOR讀取三通道圖像,即使輸入是灰度圖像,也會有三通道,只是每個通道擁有相同的數據
cv::IMREAD_GRAYSCALE讀取單通道圖像
cv::IMREAD_ANYCOLOR通道數由文件實際通道數(不超過3)
cv::IMREAD_ANYDEPTH允許加載超過8bit深度
cv::IMREAD_UNCHANGED相當于cv::IMREAD_ANYCOLOR和cv::IMREAD_ANYDEPTH組合使用,可保留alpha通道。

使用cv::imwrite()保存圖像

bool cv::imwrite(const string& filename, InputArray image, const vector<int>& params=vector<int>())

作用:保存圖像,成功返回true,否則返回false。

常用擴展名擴展名格式大小通道
.jpg或.jpegbaseline JPEG8位單通道或三通道
.jp2JPEG20008位或16位單通道或三通道
.tif或.tiffTIFF8位或16位單通道、三通道或四通道
.pngPNG8位或16位單通道、三通道或四通道
.bmpBMP8位單通道、三通道或四通道
.ppm或.pgmNetPBM8位單通道(PGM)和三通道(PPM)
params的使用標志含義取值范圍默認值
cv::IMWRITE_JPG_QUALITYJPEG的質量0~10095
cv::IMWRITE_PNG_COMPRESSIONPNG壓縮值0~93
cv::IMWRITE_PXM_BINARY對PPM、PGM或PBM文件是否使用二值格式0或11

關于codecs的一些注釋

用于圖像處理的庫通常被叫做codecs(co-mpression and dec-compress libraries-s)。OpenCV對一些圖片格式自帶編碼解碼庫,對于這些有一下三中選擇:

① 不使用這些編碼解碼庫;

② 使用OpenCV所提供的編碼解碼庫;

③ 使用相應的拓展庫(如libjpeg、libpng等)。

在Windows系統中默認選②選項,而在OS X或Linux系統上,默認選③選項。

圖片的編碼與解碼

使用cv::imencode()壓縮圖像

void cv::imencode(const string& ext, InputArray img, vector<uchar>& buf, const vector<int>& params=vector<int>())

作用:對圖像進行編碼。

參數列表參數含義
ext文件擴展名,用于函數與對應的編碼壓縮方式相關聯。指明格式并幫助系統索引對應編碼庫
img要被壓縮的圖像數據
buf用來存儲編碼壓縮后的圖像數據的字符數組
params指明要使用編碼器的輸入參數

使用cv::imdecode()解碼文件

cv::Mat cv::imdecode(InputArray buf, int flags=cv::IMREAD_COLOR)

作用:將字節流數據解碼成數組形式的圖像。

視頻處理

使用cv::VideoCapture對象讀取視頻流

cv::VideoCapture::VideoCapture(const string& filename)

cv::VideoCapture::VideoCapture(int device)

cv::VideoCapture::VideoCapture()

作用:打開視頻文件或攝像機。打開成功則cv::VideoCapture::isOpen()會返回true,否則返回false。

構造設備參數時,傳入的標識符是相機的域索引和相機索引之和。相機索引是指系統中攝像機設備的索引,從0開始計數。相機域表明我們用何種相機,如下表所示。

相機域常量相機捕捉常數數值相機捕捉常數數值相機捕捉常數數值
cv::CAP_ANY0cv::CAP_DSHOW700cv::CAP_OPENNI21600
cv::CAP_MIL100cv::CAP_PVAPI800cv::CAP_OPENNI2_ASUS1610
cv::CAP_VFW200cv::CAP_OPENNI900cv::CAP_GPHOTO21700
cv::CAP_V4L200cv::CAP_OPENNI_ASUS910cv::CAP_GSTREAMER1800
cv::CAP_V4L2200cv::CAP_ANDROID1000cv::CAP_FFMPEG1900
cv::CAP_FIREWIRE300cv::CAP_XIAPI1100cv::CAP_IMAGES2000
cv::CAP_FIREWARE300cv::CAP_AVFOUNDATION1200cv::CAP_ARAVIS2100
cv::CAP_IEEE11394300cv::CAP_GIGANETIX1300cv::CAP_OPENCV_MJPEG2200
cv::CAP_DC1394300cv::CAP_MSMF1400cv::CAP_INTEL_MFX2300
cv::CAP_QT500cv::CAP_WINRT1410cv::CAP_XINE2400
cv::CAP_UNICAP600cv::CAP_INTELPERC1500??

當傳入的標識符為-1時,則OpenCV會彈出一個選擇窗口,可手動選擇希望使用的相機。

最后一種形式只是直接創建一個VideoCapture對象,無法直接使用,需要調用cv::VideoCapture::open()函數來指定文件名或設備號,和前兩種形式一樣。

使用cv::VideoCapture::read()從視頻流中讀取圖像

bool?cv::VideoCapture::read(OutputArray img)

作用:從文件中讀取下一幀數據,并將結果存入img中,并會自動更新。讀取成功返回true,讀取失敗返回false。

使用cv::VideoCapture::operator>>()從視頻流讀取圖像數據

cv::VideoCapture&?cv::VideoCapture::operator>>(Mat& img)

作用:重載輸入流操作符,從文件中讀取下一幀數據,并將結果存入img中。

使用cv::VideoCapture::grab()和cv::VideoCapture::retrieve()從視頻流中讀取圖像數據

bool?cv::VideoCapture::grab()

作用:將當前可使用的圖像數據拷貝至用戶看不到的一個內存緩存區。抓取的圖像幀是未處理的,該函數只是設計用于將原始數據盡快獲取到電腦。

bool?cv::VideoCapture::retrieve(OutputArray image, int channel)

作用:對內部緩存數據進行必要的圖像解碼、內存分配與拷貝,最后以Mat形式的序列將圖像幀返回。

相機屬性cv::VideoCapture::get()和cv::VideoCapture::set()

double cv::VideoCapture::get(int propid)

bool cv::VideoCapture::set(int propid, double value)

作用:獲取或設置元數據(meta data)。

視頻捕捉屬性常量ID是否只在攝像頭模式下可以使用含義
cv::CAP_PROP_POS_MSEC?視頻文件中當前位置(毫秒)或視頻捕獲時間戳
cv::CAP_PROP_POS_FRAMES?從0開始下一幀的索引
cv::CAP_PROP_POS_AVI_RATIO?視頻的相對位置
cv::CAP_PROP_FRAME_WIDTH?視頻幀的像素寬度
cv::CAP_PROP_FRAME_HEIGHT?視頻幀的像素高度
cv::CAP_PROP_FPS?錄制視頻的幀速率
cv::CAP_PROP_FOURCC?四個字符代碼指示編解碼
cv::CAP_PROP_FRAME_COUNT?視頻文件的總幀數
cv::CAP_PROP_FORMAT?返回Mat對象的格式(如CV_8UC3)
cv::CAP_PROP_MODE?表示捕捉模式,值是特定于正在使用的視頻后端(如DC1394)
cv::CAP_PROP_BRIGHTNESS相機的亮度設置
cv::CAP_PROP_CONCAT相機的對比度設置
cv::CAP_PROP_SATURATION相機的飽和度設置
cv::CAP_PROP_HUE相機的色調設置
cv::CAP_PROP_GAIN相機的增益設置
cv::CAP_PROP_EXPOSURE相機的曝光設置
cv::CAP_PROP_CONVERT_RGB如果非0,獲取的圖像將被轉換為具有三個通道
cv::CAP_PROP_WHITE_BALANCE相機的白平衡設置
cv::CAP_PROP_RECTIFICATION立體相機整流標志(僅適用于DC1934-2.x)

使用cv::VideoWriter對象寫入視頻

cv::VideoWriter::VideoWriter(const string& filename, int fourcc, double fps, Size frame_size, bool is_color=true)

cv::VideoWriter::VideoWriter()

作用:創建一個VideoWriter對象,is_color為true則傳入彩色圖,反之可以傳入灰度圖。同樣第二種形式不能直接使用,需要調用cv::VideoWriter::open()函數進行配置。

判斷是否初始化成功,可通過cv::VideoWriter::isOpen()的返回值進行判斷。

使用cv::VideoWriter::write()函數完成圖像幀的寫入

cv::VideoWriter::write(const Mat& img)

作用:完成圖像幀的寫入,圖像必須和cv::VideoWriter具有相同的圖像尺寸,如果是彩色必是三通道,反之使用單通道。

使用cv::VideoWriter::operator<<()將圖像寫入視頻

cv::VideoWriter&?cv::VideoWriter::operator<<(Mat& img)

作用:重載輸出流操作符,將img存入視頻文件。

數據存儲

作為對標準視頻壓縮方式的補充,OpenCV提供了一種序列化與反序列化的機制,用于將不同數據類型的數據已YAML或XML格式寫入磁盤或者從磁盤讀取。這些方法可以用來加載或者保存任何OpenCV的數值變量到一個文件中。

cv::FileStorage的寫入

cv::FileStorage::FileStorage(string filename, int flag)

cv::FileStorage::FileStorage()

作用:創建FileStorage對象(代表XML或YAML格式的數據文件),flag指定功能,寫入時可為cv::FileStorage::WRITE和cv::FileStorage::APPEND。同樣第二種形式不能直接使用,需要調用cv::FileStorage::open()函數進行配置。

寫入時可以使用重載輸出操作符函數cv::FileStorage::operator<<()進行寫入。寫完時調用cv::FileStorage::release()關閉該文件。

cv::FileStorage內部數據的存儲形式主要有mapping和sequence,在最頂層是一個mapping,其中可以嵌套mapping和sequence。新建mapping或sequence分別使用{}和[]。

#include "stdafx.h" #include <opencv2/opencv.hpp> #include <time.h>// 使用cv::FileStorage創建一個test.yml參數文件 int main() {// 創建FileStorage對象,實現其寫入功能cv::FileStorage fs("test.yml", cv::FileStorage::WRITE);// 寫入內容fs << "frameCount" << 5;// 獲取當前時間并寫入time_t rawtime;time(&rawtime);fs << "calibrationDate" << asctime(localtime(&rawtime));// 生成矩陣,并寫入cv::Mat cameraMatrix = (cv::Mat_<double>(3, 3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1);cv::Mat distCoeffs = (cv::Mat_<double>(5, 1) << 0.1, 0.01, -0.001, 0, 0);fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs;// 隨機生成數及數組并寫入fs << "features" << "[";for (int i = 0; i < 3; i++) {int x = rand() % 640;int y = rand() % 480;uchar lbp = rand() % 256;fs << "{:" << "x" << x << "y" << y << "lbp" << "[:";for (int j = 0; j < 8; j++) {fs << ((lbp >> j) & 1);}fs << "]" << "}";}fs << "]";// 關閉文件fs.release();return 0; }

?用記事本打開test.yml文件,內容如下:

cv::FileStorage讀取文件

cv::FileStorage::FileStorage(string filename, int flag)

cv::FileStorage::FileStorage()

作用:創建FileStorage對象(代表XML或YAML格式的數據文件),flag指定功能,讀取時可為cv::FileStorage::READ。同樣第二種形式不能直接使用,需要調用cv::FileStorage::open()函數進行配置。

讀取時可以使用重載輸出操作符函數cv::FileStorage::operator>>()進行讀取,得到的不是直接的數據,而是FileNode對象。若該值是基本數據類型,則可以通過強制類型轉換直接獲取;若該值是mapping,則通過重載操作符[]并給定所需關鍵字訪問;若該值是sequence,則通過重載操作符[]并給定整型參數訪問,也可使用cv::FileStorageIterator迭代器進行訪問。

讀完時調用cv::FileStorage::release()關閉該文件。

cv::FileNode

FileNode的基本使用在上述內容中已做過介紹,下面將主要針對cv::FileStorageIterator進行介紹。

給定一個FileNode對象,通過cv::FileNode::begin()和cv::FileNode::end()可以分別返回該mapping或者sequence的首元素的迭代器和末尾首元素的迭代器。該迭代器對象可以通過cv::FileStorageIterator::operator*()來進行解引用操作并返回迭代器對應的位置的FileNode對象,并通過自增和自減來控制迭代器。

若其對一個mapping進行遍歷,返回的FileNode對象將會有名字屬性,可通過cv::FileNode::name()得到。同樣,通過cv::FileNode::type()可獲得cv::FileNode中定義的枚舉類型。

cv::FileNode的成員函數示例說明
cv::FileNode fn文件節點對象的默認構造函數
cv::FileNode fn1(fn0)文件節點對象的復制構造函數,從節點fn0創建節點fn1
cv::FileNode fn1(fs,node)文件節點對象構造函數,從C風格的CvFileStorage*指針和C風格的CvFileNode*指針節點創建FileNode對象

fn[ (string) key ]

fn[ (const char*) key ]

命名子串(映射節點)的STL字符串或C字符串存取器,將秘鑰轉換為適當的子節點。
fn[ (int) id ]子編號(序列節點)的訪問;將ID轉換為相應的子節點
fn.type()返回節點類型enum
fn.empty()確定節點是否為空
fn.isNone()確定節點是否為None
fn.isSeq()確定節點是否為序列
fn.isMap()確定節點是否為映射

fn.isInt()

fn.isReal()

fn.isString()

確定節點是否為整數

確定節點是否為浮點數

確定節點是否為字符串

fn.name()如果節點是映射的子節點,返回節點名稱
size_t sz= fn.size()如果是序列或映射,返回節點中的元素數量,否則返回1。

(int) fn

(float) fn

(double) fn

(string) fn

從包含整數的節點中提取

從包含32位浮點數的節點中提取

從包含64位浮點數的節點中提取

從包含字符串的節點中提取

cv::FileNode::type()可能的返回值示例說明
cv::FileNode::NONE = 0節點類型為None
cv::FileNode::INT = 1節點包含一個整數

cv::FileNode::REAL = 2

cv::FileNode::FLOAT = 2

節點包含一個浮點數(不分精度)

cv::FileNode::STR = 3

cv::FileNode::STRING = 3

節點包含一個字符串
cv::FileNode::REF = 4節點包含參考(即復合對象)
cv::FileNode::SEQ = 5節點本身是其他節點的序列
cv::FileNode::MAP = 6節點本身是其他節點的映射
cv::FileNode::FLOW = 8節點是序列或映射的緊湊表示
cv::FileNode::USER = 16節點是注冊對象(如矩陣)
cv::FileNode::EMPTY = 32節點沒有復制給它
cv::FileNode::NAMED = 64節點是映射的子節點(即它有一個名字)

注:一個FileNode除了擁有前8種屬性之外還可以同時擁有最后四個中的一個或全部屬性。

#include "stdafx.h" #include <opencv2/opencv.hpp>// 使用FileStorage來讀取test.yml文件 int main() {// 創建FileStorage對象,實現讀取功能cv::FileStorage fs("D:\\personal-data\\opencv\\example8-2\\example8-2\\test.yml", cv::FileStorage::READ);// 對FileNode進行強制類型轉換,得到數據int frameCount = (int)fs["frameCount"];// 使用重載>>操作符std::string date;fs["calibrationDate"] >> date;cv::Mat cameraMatrix, distCoeffs;fs["cameraMatrix"] >> cameraMatrix;fs["distCoeffs"] >> distCoeffs;std::cout << "frameCount" << frameCount << std::endl;std::cout << "calibrationDate" << date << std::endl;std::cout << "cameraMatrix" << cameraMatrix << std::endl;std::cout << "distCoeffs" << distCoeffs << std::endl;cv::FileNode features = fs["features"];cv::FileNodeIterator it = features.begin(), it_end = features.end();int idx = 0;std::vector<uchar> lbpval;// 使用迭代器遍歷序列for (; it != it_end; ++it, idx++){std::cout << "features #" << idx << ": ";std::cout << "x=" << (int)(*it)["x"] << ", y=" << (int)(*it)["y"] << ", lbp: (";(*it)["lbp"] >> lbpval;for (int i = 0; i < (int)lbpval.size(); i++){std::cout << " " << (int)lbpval[i];}std::cout << ")" << std::endl;}//關閉文件fs.release();return 0; }

運行結果:

frameCount5 calibrationDateMon Aug 20 20:20:03 2018cameraMatrix[1000, 0, 320;0, 1000, 240;0, 0, 1] distCoeffs[0.1;0.01;-0.001;0;0] features #0: x=41, y=227, lbp: ( 0 1 1 1 1 1 0 1) features #1: x=260, y=449, lbp: ( 0 0 1 1 0 1 1 0) features #2: x=598, y=78, lbp: ( 0 1 0 0 1 0 1 0)

?

總結

以上是生活随笔為你收集整理的OpenCV可移植图形工具HighGUI实现图像和视频操作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。