相對於之前一個所介紹的 Trackbar, 這次要介紹的就像是一塊小蛋糕 (a piece of cake)
Camera Capture
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include "opencv2/opencv.hpp" using namespace cv; int main(int, char**) { VideoCapture cap(0); // open the default camera if (!cap.isOpened()) // check if we succeeded return -1; Mat edges; namedWindow("default", WINDOW_AUTOSIZE); namedWindow("edges", WINDOW_AUTOSIZE); for(;;) { Mat frame; cap >> frame; // get a new frame from camera // show default frame imshow("default", frame); // show edges frame cvtColor(frame, edges, COLOR_BGR2GRAY); GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5); Canny(edges, edges, 0, 30, 3); imshow("edges", edges); if(waitKey(30) >= 0) break; } // the camera will be deinitialized automatically in VideoCapture destructor return 0; } |
這VideoCaptrure的建構子只需要一個參數, 填入的數字就代表著要開啟第幾個camera
如果填入了 0, 則會開啟default的 camera
喵用手上的玩偶照了張相, 展示上面的程式碼會有的效果
- default
需要解說的部分
說實在也蠻多的
就先從簡單的開始
cap >> frame; // get a new frame from camera
這邊是從capture當中讀取一張圖
其實方法等同於
cap.read(frame);
說簡單其實也不太簡單
因為 frame本身是 Mat的物件
但是呢~ cap.read 卻需要帶入 OutputArray物件
bool VideoCapture::read(OutputArray image)
那~ 又為什麼可以編譯得過呢!?!?!
主要是因為 OutputArray 本身是經過些處理
使得他自帶constructor的功能, 而參數就是我們所放進去的Mat
bool VideoCapture::read(OutputArray image) --- 分隔線 --- typedef const _OutputArray& OutputArray; --- 分隔線 --- class CV_EXPORTS _OutputArray : public _InputArray { public: ... _OutputArray(Mat& m); } --- 分隔線 --- inline _OutputArray::_OutputArray(Mat& m) { init(MAT+ACCESS_WRITE, &m); }
看起來非常美妙對吧
附註
關於這個部分
特地寫了個程序, 讓有好奇心的朋友來玩看看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #include <iostream> #include <stdio.h> using namespace std; class Mat { int val[3]; }; class _OutputArray { public: _OutputArray(Mat& m); protected: int flags; void* obj; void init(int _flags, const void* _obj); }; enum { ACCESS_READ=1<<24, ACCESS_WRITE=1<<25, ACCESS_RW=3<<24, ACCESS_MASK=ACCESS_RW, ACCESS_FAST=1<<26 }; enum { KIND_SHIFT = 16, NONE = 0 << KIND_SHIFT, MAT = 1 << KIND_SHIFT, }; inline void _OutputArray::init(int _flags, const void* _obj) { flags = _flags; obj = (void*)_obj; } inline _OutputArray::_OutputArray(Mat& m) { printf(" _OutputArray Mat& m"); // <== key word init(MAT+ACCESS_WRITE, &m); } typedef const _OutputArray& OutputArray; // Test Function void read(OutputArray m) { // Do Nothing } int main() { Mat frame; read(frame); return 0; } |
困難的部分
恩...
困難的部分
主要是跟圖形轉換有關係
cvtColor(frame, edges, COLOR_BGR2GRAY); GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5); Canny(edges, edges, 0, 30, 3);
也因為有點太困難
喵還是用另外的文章來分別講解~
繼續讓這篇維持一個小蛋糕的形式吧 喵~
沒有留言:
張貼留言