初始openCV之入門實例五起

剛剛在Qt上配置好了OpenCV,寫了五個較爲基礎的實例,用到一些比較常用的函數。記錄一下。

首先都是在QT中新建的Qt Console Application項目,先在.pro文件中加入:

INCLUDEPATH += D:/opencv2.4.12/opencv/sources/output/include \
               D:/opencv2.4.12/opencv/sources/output/include/opencv \
               D:/opencv2.4.12/opencv/sources/output/include/opencv2
LIBS += D:/opencv2.4.12/opencv/sources/output/x86/mingw/lib/libopencv_*

實例一:顯示圖片

#include <QCoreApplication>
#include <opencv/highgui.h>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //將圖片加載至內存
    IplImage* img = cvLoadImage("D:/Pictures/1.jpg");
    if (img == NULL)
       return 1;
    //在屏幕上創建一個窗口
    //第一個參數爲窗口標題,第二個參數可以是0(窗口大小不會因圖像的大小而改變,
    //圖像只能在窗口中根據窗口的大小進行拉伸或縮放)
    //或CV_WINDOW_AUTOSIZE(窗口會根據圖像的實際大小自動進行拉伸或縮放,以容納圖像)
    cvNamedWindow("abc",CV_WINDOW_AUTOSIZE);
    //顯示圖像,第一個參數爲窗口名稱,第二個參數爲圖像地址
    cvShowImage("abc",img);
    //使程序暫停,等待用戶觸發一個按鍵操作。值正數時爲ms,0或負數時一直等待。
    cvWaitKey(0);
    //釋放爲圖片分配的內存
    cvReleaseImage(&img);
    //銷燬窗口
    cvDestroyAllWindows();
    return a.exec();
}


實例二:播放視頻

#include <QCoreApplication>
#include <highgui.h>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //創建窗口
    cvNamedWindow("Example2", CV_WINDOW_AUTOSIZE);
    //讀入視頻.avi
    CvCapture* capture = cvCreateFileCapture("D:/Pictures/11.avi");
    IplImage* frame;
    while(1)
    {
        //將下一幀視頻文件存入內存,返回一個對應當前幀的指針
        frame = cvQueryFrame(capture);
        if(!frame)
            break;
        cvShowImage("Example2", frame);
        char c = cvWaitKey(33);
        //如果用戶觸發了一個按鍵,c會被設置成這個按鍵的ASCII碼,否則c爲-1.
        //如果用戶觸發了Esc鍵(ASCII碼爲27),則循環退出,讀入視頻停止
        if(c == 27)
            break;
    }
    cvReleaseCapture(&capture);
    cvDestroyWindow("Example2");
    //此處不用cvReleaseImage(&frame)是因爲cvQueryFrame使用已經在cvCapture結構中分配好的內存
    //當cvCapture結構被釋放後,每一幀圖像所對應的內存空間就會被釋放。
    return a.exec();
}

實例三:播放視頻,可以拖動滾動條控制進度並且滾動條會自動刷新

/*通過添加一個全局變量來表示滾動條位置並且添加一個回調函數來更新變量以及重新設置視頻讀入位置。*/
#include <QCoreApplication>
#include <highgui.h>
#include <cv.h>
#include <QDebug>
//全局變量,分別爲滾動條位置和回調函數需要的CvCapture對象
int g_slider_position = 0;
CvCapture* g_capture = NULL;
//回調函數,使其在滾動條被拖動時調用。
void onTrackbarSlide(int pos)
{
    cvSetCaptureProperty( //設置CvCapture對象的各種屬性。配套的函數爲cvGetCaptureProperty()。
                g_capture, //對象名
                CV_CAP_PROP_POS_FRAMES,//表示我們以幀數來設置讀入位置。
                                       //若想通過視頻長度比例來設置讀入位置,可以用AVI_RATIO代替FRAMES實現
                pos);//把新的滾動條位置作爲參數傳入
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    cvNamedWindow("Example3", CV_WINDOW_AUTOSIZE);
    g_capture = cvCreateFileCapture("D:/Pictures/11.avi");
    int frames = (int)cvGetCaptureProperty( //用來獲取視頻文件的總幀數以對滾動條進行設置
                g_capture, //對象
                CV_CAP_PROP_FRAME_COUNT);
    if(frames != 0)
    {
        //參數3:Pointer to the function to be called every time the slider changes position
        cvCreateTrackbar(                //創建滾動條
                    "Position",          //滾動條名稱
                    "Example3",          //滾動條所屬窗口
                    &g_slider_position,  //滾動條位置變量
                    frames,              //滾動條最大值
                    onTrackbarSlide      //回調函數,其第一個參數爲滾動條位置
                    );
    }
    IplImage* frame;
    while(1)
    {
        //將下一幀視頻文件存入內存,返回一個對應當前幀的指針
        frame = cvQueryFrame(g_capture);
        if(!frame)
            break;
        cvShowImage("Example3", frame);
        //如果用戶觸發了一個按鍵,c會被設置成這個按鍵的ASCII碼,否則c爲-1.
        char c = cvWaitKey(10);
        //如果用戶觸發了Esc鍵(ASCII碼爲27),則循環退出,讀入視頻停止
        if(c == 27)
            break;
        int currentFrame = (int)cvGetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES);
        //此句將更新
        cvSetTrackbarPos("Position", "Example3", currentFrame);
    }
    cvReleaseCapture(&g_capture);
    cvDestroyWindow("Example3");
    return a.exec();
}
/*
//關鍵函數原型:
int createTrackbar(
   const String& trackbarname,//Name of the created trackbar.
   const String& winname,     //Name of the window that will be used as a parent of the created trackbar.
   int* value,                //Optional pointer to an integer variable whose value reflects the position of the slider.
                              //Upon creation, the slider position is defined by this variable.
   int count,                 //Maximal position of the slider. The minimal position is always 0.
   TrackbarCallback onChange=0,//Pointer to the function to be called every time the slider changes position.
                              //This function should be prototyped as void Foo(int,void*); ,
                              //where the first parameter is the trackbar position and the second parameter
                              //is the user data (see the next parameter). If the callback is the NULL pointer,
                              //no callbacks are called, but only value is updated.
   void* userdata=0           //User data that is passed as is to the callback. 
                              //It can be used to handle trackbar events without using global variables.
)
        The function createTrackbar creates a trackbar (a slider or range control)
        with the specified name and range, assigns a variable value to be a position synchronized
        with the trackbar and specifies the callback function onChange to be called on the trackbar position change.
        The created trackbar is displayed in the specified window winname.
*/

實例四:對圖像放大、縮小,平滑處理,進行邊緣檢測等

這個例子使用到的函數主要是cvPryUp、cvPryDwon、cvSmooth、cvCanny等。

#include <QCoreApplication>
#include <assert.h>
#include <cv.h>
#include <highgui.h>
IplImage* doPyrDown(IplImage* in) //圖像下采樣,將圖片變爲原來的1/2。注意cvSize()的大小。否則會出現錯誤
{
    //assert(in->width % 2 == 0 && in->height % 2 == 0);//其作用是如果它的條件返回錯誤,則終止程序執行
    IplImage* out = cvCreateImage(
                cvSize(in->width / 2, in->height / 2),
                in->depth,
                in->nChannels
    );
    cvPyrDown(in, out, CV_GAUSSIAN_5x5);
    return(out);
}
IplImage* doPyrUp(IplImage* in) //圖像上採樣,將圖片變成原來的2倍。注意cvSize()的大小。否則會出現錯誤
{
   // assert(in->width % 2 == 0 && in->height % 2 == 0);//其作用是如果它的條件返回錯誤,則終止程序執行
    IplImage* out = cvCreateImage(
                cvSize(in->width * 2, in->height * 2),
                in->depth,
                in->nChannels
    );
    cvPyrUp(in, out, CV_GAUSSIAN_5x5);
    return(out);
}
IplImage* doCanny(   //Canny是常用的邊緣檢測方法,其特點是試圖將獨立邊的候選像素拼裝成輪廓
        IplImage* in,
        double lowThresh,
        double highThresh,
        double aperture
){
    if(in->nChannels != 1) //canny
        return 0;
    IplImage* out = cvCreateImage(
                cvGetSize(in),
                IPL_DEPTH_8U,
                1
    );
    cvCanny(
            in,            //單通道輸入圖像.
            out,           //單通道存儲邊緣的輸出圖像
            lowThresh,     //第一個閾值,小閾值用來控制邊緣連接
            highThresh,    //第二個閾值,大的閾值用來控制強邊緣的初始分割
            aperture       //Sobel 算子內核大小
    );
    return(out);
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    IplImage* img = cvLoadImage("D:/Pictures/puma.jpg");
    if (img == NULL)
       return 1;
    cvNamedWindow("primary",CV_WINDOW_AUTOSIZE);
    cvNamedWindow("smooth",CV_WINDOW_AUTOSIZE);
    cvShowImage("primary", img);
    IplImage* img_out = cvCreateImage(  //分配圖像結構空間
                cvGetSize(img),         //CvSize結構
                IPL_DEPTH_8U,           //各通道每個像素點的數據類型
                3                       //通道總數
    );
    //使用每個像素周圍3*3區域進行高斯平滑處理
    cvSmooth(img, img_out, CV_GAUSSIAN, 3, 3);
    cvShowImage("smooth", img_out);
    IplImage* pyrDown = doPyrDown(img);
    IplImage* pyrUp = doPyrUp(img);
    cvNamedWindow("pyrDown", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("pyrUp", CV_WINDOW_AUTOSIZE);
    cvShowImage("pyrDown", pyrDown);
    cvShowImage("pyrUp", pyrUp);
    IplImage* solo_img = cvLoadImage("D:/Pictures/puma.jpg", 0);
    /*注意:cvCanny只接受單通道圖像作爲輸入,因此cvLoadImage的第二給參數表示是否加載有顏色的圖像,
      因設爲0,表示單通道圖像,否則會出現編譯錯誤,會提示canny.cpp不合法。
    */
    cvNamedWindow("solo_img", CV_WINDOW_AUTOSIZE);
    cvShowImage("solo_img", solo_img);
    IplImage* canny = doCanny(solo_img, 50, 150, 3);
    cvNamedWindow("canny", CV_WINDOW_AUTOSIZE);
    cvShowImage("canny", canny);
    cvWaitKey(0);
    cvReleaseImage(&solo_img);
    cvReleaseImage(&canny);
    cvReleaseImage(&img);
    cvReleaseImage(&img_out);
    cvReleaseImage(&pyrDown);
    cvReleaseImage(&pyrUp);
  //  cvDestroyWindow("pyrDown");
  //  cvDestroyWindow("pyrUp");
  //  cvDestroyWindow("primary");
  //  cvDestroyWindow("smooth");
  //  cvDestroyWindow("canny");
    cvDestroyAllWindows();
    return a.exec();
}


實例五:實現讀入一個彩色視頻文件並以灰度格式輸出

//用來實現讀入一個彩色視頻文件並以灰度格式輸出這個視頻
#include <QCoreApplication>
#include <cv.h>
#include <highgui.h>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    CvCapture* capture = 0;
    capture = cvCreateFileCapture("D:/Pictures/11.avi");//打開視頻文件
    if(!capture)
    {
        return -1;
    }
    IplImage* bgr_frame = cvQueryFrame(capture);//init the video read
    double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
    CvSize size = cvSize(
                (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH),
                (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT)
    );
    CvVideoWriter *writer = cvCreateVideoWriter(
                "D:/Pictures/11_output.avi",      //輸出視頻文件名
                CV_FOURCC('M', 'J', 'P', 'G'),    //四個字符用來表示壓縮幀的codec
                fps,                              //被創建視頻流的幀率
                size                              //視頻流的大小
                //int is_color=1,第五個參數。s_color 如果非零,編碼器將希望得到彩色幀並進行編碼;否則,是灰度幀(只有在Windows下支持這個標誌)
    );
    IplImage* logpolar_frame = cvCreateImage(
                size,
                IPL_DEPTH_8U,
                3
    );
    while((bgr_frame = cvQueryFrame(capture)) != NULL)
    {
        cvLogPolar(               //把圖像映射到極指數空間
                   bgr_frame,         //輸入圖像
                   logpolar_frame,    //輸出圖像
                   cvPoint2D32f(bgr_frame->width / 2, bgr_frame->height / 2),//變換的中心,輸出圖像在這裏最精確
                   40,// 幅度的尺度參數
                   CV_INTER_LINEAR + CV_WARP_INVERSE_MAP //插值方法和以下選擇標誌的結合
                   //CV_WARP_FILL_OUTLIERS-填充輸出圖像所有像素,如果這些點有和外點對應的,則置零。
                   //CV_WARP_INVERSE_MAP- 表示矩陣由輸出圖像到輸入圖像的逆變換,並且因此可以直接用於像素插值。
                   //否則,函數從map_matrix中尋找逆變換。
        );
        cvWriteFrame(
                    writer,          //視頻寫入器結構
                    logpolar_frame   //被寫入的幀
        );
    }
    cvReleaseVideoWriter(&writer);
    cvReleaseImage(&logpolar_frame);
    cvReleaseCapture(&capture);
    return a.exec();
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章