1. 程式人生 > >openCV中視訊的讀入、RGB通道分離以及滑鼠左擊反饋位置、灰度

openCV中視訊的讀入、RGB通道分離以及滑鼠左擊反饋位置、灰度


啥話不說,先上程式碼:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace std;
using namespace cv;

    void onMouse(int event, int x, int y, int flags, void* param)
    {
        Mat *im = reinterpret_cast<Mat*>(param);
        if(event==CV_EVENT_LBUTTONDOWN)
        {
                std::cout<<"at("<<x<<","<<y<<")value is:"
                    <<static_cast<int>(im->at<uchar>(cv::Point(x,y)))<<std::endl;
        }
    }
int main(int argc, char *argv[])
{
    VideoCapture capture("1.avi");
    if(!capture.isOpened())
    {
        cout<<"fail to open."<<endl;
    }
    double rate = capture.get(CV_CAP_PROP_FPS);
    bool stop(false);
    Mat frame;

    char ch;
    cout<<"please input the channel you want to see:"<<endl;
    cin>>ch;

    int delay=1000/rate;
    while(!stop)
    {
        if(!capture.read(frame))
            break;
        vector<Mat> channels;
        Mat dst;
        split(frame,channels);
        switch(ch)
        {
            case 'b':
            dst=channels[0];
            break;
            case 'g':
            dst=channels[1];
            break;
            case 'r':
            dst=channels[2];
            break;
        }

        namedWindow("Img",CV_WINDOW_AUTOSIZE);
        imshow("Img",dst);
        cv::setMouseCallback("Img",onMouse,reinterpret_cast<void*>(&frame));
            if(waitKey(delay)>=0)
            {
                stop=true;
            }
    }
    waitKey(0);
    return 0;
}

程式碼解釋:

VideoCapture capture("1.avi");

讀入視訊至capture中;
if(!capture.isOpened())
    {
        cout<<"fail to open."<<endl;
    }
利用isOpened( )判斷匯入視訊是否成功;
 double rate = capture.get(CV_CAP_PROP_FPS);
匯入該視訊幀率,幀率是每秒顯示幀數;
 char ch;
    cout<<"please input the channel you want to see:"<<endl;
    cin>>ch;

輸入所需顯示通道;
int delay=1000/rate;
if(waitKey(delay)>=0)
            {
                stop=true;
            }
首先delay代表的是一幀需要停留多少毫秒,量綱分析:1/(1/s)=s;

該條件語句下,首先執行waitKey( ),意味著停留一幀的時間,然後進行判斷,由於當delay>0時無按鍵按下時waitKey返回-1,此時若有按鍵按下,則返回該按鍵ASCII碼,則if成立,跳出while迴圈;

if(!capture.read(frame))
            break;

讀取視訊某一幀並檢驗是否正確讀取;
split(frame,channels);

將該圖分為三個通道放入向量channels中;
switch(ch)
        {
            case 'b':
            dst=channels[0];
            break;
            case 'g':
            dst=channels[1];
            break;
            case 'r':
            dst=channels[2];
            break;
        }

        namedWindow("Img",CV_WINDOW_AUTOSIZE);
        imshow("Img",dst);

選擇需要通道並從channels中獲取;
 cv::setMouseCallback("Img",onMouse,reinterpret_cast<void*>(&frame));

void onMouse(int event, int x, int y, int flags, void* param)
    {
        Mat *im = reinterpret_cast<Mat*>(param);
        if(event==CV_EVENT_LBUTTONDOWN)
        {
                std::cout<<"at("<<x<<","<<y<<")value is:"
                    <<static_cast<int>(im->at<uchar>(cv::Point(x,y)))<<std::endl;
        }
    }

實現滑鼠點選獲取座標與灰度值,onMouse為定義需要執行的滑鼠操作,此處定義為輸出x,y及其灰度值。