[OPENCV] Camera capture

今天要介紹的東西很容易
相對於之前一個所介紹的 Trackbar, 這次要介紹的就像是一塊小蛋糕 (a piece of cake)

Camera Capture

使用openCV最大的好處, 就是方便
人家都說我們要在站在巨人的肩膀上
在這裡就體現了這句話

喵這次主要介紹的就是
VideoCapture
程式碼如下

 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




  • edges



  • 需要解說的部分
    說實在也蠻多的

    就先從簡單的開始


    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);
    

    也因為有點太困難
    喵還是用另外的文章來分別講解~
    繼續讓這篇維持一個小蛋糕的形式吧 喵~

    沒有留言:

    張貼留言

    OpenGL 閱讀筆記 (二) OpenGL基本操作

    這邊虎喵跳過glfw/glew的初始化, 先來提一下OpenGL的基本操作方式 前面也提到過, OpenGL是一個類C的語言, 因此使用C/C++的攻城獅們應該會感到很熟悉. OpenGL的基本動作循環如下: 每一行code的解釋如下: // 本地變數,...