《學習OpenCV》隨筆——第2章 OpenCV入門


《學習OpenCV》隨筆——第2章 OpenCV入門

 

     第一章部分由於大致屬於介紹OpenCV的部分,其中着重強調Intel在這方面所做的貢獻。誠然,開源者都有一顆博愛之心和虛心的、積極進取的心態吧。

     從第二章開始,這本書才開始有了一定的可以寫的東西。寫博客的目的還是老樣子——以寫促學。

     在上代碼之前,還需要強調一下,在OpenCV的官網下載的OpenCV 3.0beta版本中,有一些文件(庫)的文件組織結構通2.x版本有所出入,導致網上教程有一定的不同。這里一定注意。

 


 

筆者於2015年5月25日01:59注

     在這里,我們要注意一些地方:

1、在Qt 中使用,如果使用MSVC編譯器,則具體編譯步驟遠沒有MingWs的復雜。只要系統路徑注意一些,然后再pro文件中加入

 

INCLUDEPATH+=E:\opencv2.49\opencv\build\include\opencv2\

 

E:\opencv2.49\opencv\build\include\opencv\

 

E:\opencv2.49\opencv\build\include

 

CONFIG(release,debug|release)

 

{

 

LIBS+=E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_calib3d249.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_contrib249.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_core249.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_features2d249.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_flann249.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_gpu249.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_highgui249.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_imgproc249.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_legacy249.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_ml249.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_objdetect249.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_ts249.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_video249.lib

 

}

 

CONFIG(debug,debug|release)

 

{

 

LIBS+=E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_calib3d249d.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_contrib249d.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_core249d.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_features2d249d.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_flann249d.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_gpu249d.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_highgui249d.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_imgproc249d.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_legacy249d.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_ml249d.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_objdetect249d.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_ts249d.lib\

 

E:\opencv2.49\opencv\build\x86\vc11\lib\opencv_video249d.lib

 

}

這里的E:\opencv2.49改成自己的路徑即可。原文來自http://ask.csdn.net/questions/26810,致謝!
2、如果出現以下問題,請查看
http://www.cnblogs.com/csulennon/p/3775980.html 這個問題在vs12中出現過,有一定的實用性。

 
        

 

      我們在配置完環境后,就要進行一個引導部分。這里我們使用了一個簡短的例子:

 

#include<opencv\highgui.h>  //原書使用版本和我的不一樣,文件位置有出入

int main()
{
IplImage *img=cvLoadImage("1.png");
cvNamedWindow("Example1",CV_WINDOW_AUTOSIZE);
cvShowImage("Example1",img);
cvWaitKey(0);
cvReleaseImage(&img);
cvDestroyWindow("Example1");
}

 

      嗯,這個簡短的程序看起來還不錯,那是什么意思呢?我們扔掉書本,看一下手冊(我的版本是2.49,手冊是2.43的)里面的解釋吧。

The IplImage is taken from the Intel Image Processing Library, in which the format is native. OpenCV only supports a subset of possible IplImage formats, as outlined in the parameter list above.

      大致意思就是說IplImage這個類型來自於Intel 圖像處理庫。OpenCV這里用的是intel的IplImage格式的子集。

 

 

Loads an image from a file.

C++: Mat imread (const string& filename, int flags=1 )
Python: cv2. imread (filename [, flags]) → retval
C: IplImage* cvLoadImage (const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR )
C: CvMat* cvLoadImageM (const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR )
Python: cv. LoadImage (filename, iscolor=CV_LOAD_IMAGE_COLOR ) → None
Python: cv. LoadImageM (filename, iscolor=CV_LOAD_IMAGE_COLOR ) → None
下面的紅字挺重要的,其中提及了grayscale,這個確實不賴,這里就不上圖對比了。
Parameters:
  • filename – Name of file to be loaded.
  • flags

    Flags specifying the color type of a loaded image:

    • CV_LOAD_IMAGE_ANYDEPTH - If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit.
    • CV_LOAD_IMAGE_COLOR - If set, always convert image to the color one
    • CV_LOAD_IMAGE_GRAYSCALE - If set, always convert image to the grayscale one
    • >0 Return a 3-channel color image.

      Note

      In the current implementation the alpha channel, if any, is stripped from the output image. Use negative value if you need the alpha channel.

    • =0 Return a grayscale image.
    • <0 Return the loaded image as is (with alpha channel).

The function imread loads an image from the specified file and returns it. If the image cannot be read (because of missing file, improper permissions, unsupported or invalid format), the function returns an empty matrix ( Mat::data==NULL ). Currently, the following file formats are supported:

  • Windows bitmaps - *.bmp, *.dib (always supported)
  • JPEG files - *.jpeg, *.jpg, *.jpe (see the Notes section)
  • JPEG 2000 files - *.jp2 (see the Notes section)
  • Portable Network Graphics - *.png (see the Notes section)
  • Portable image format - *.pbm, *.pgm, *.ppm (always supported)
  • Sun rasters - *.sr, *.ras (always supported)
  • TIFF files - *.tiff, *.tif (see the Notes section)

Note

      下面這一條紅字是好東西,它是根據內容來進行格式決定,而不是根據擴展名。

  • The function determines the type of an image by the content, not by the file extension.
  • On Microsoft Windows* OS and MacOSX*, the codecs shipped with an OpenCV image (libjpeg, libpng, libtiff, and libjasper) are used by default. So, OpenCV can always read JPEGs, PNGs, and TIFFs. On MacOSX, there is also an option to use native MacOSX image readers. But beware that currently these native image loaders give images with different pixel values because of the color management embedded into MacOSX.
  • On Linux*, BSD flavors and other Unix-like open-source operating systems, OpenCV looks for codecs supplied with an OS image. Install the relevant packages (do not forget the development files, for example, “libjpeg-dev”, in Debian* and Ubuntu*) to get the codec support or turn on the OPENCV_BUILD_3RDPARTY_LIBS flag in CMake.

Note

In the case of color images, the decoded images will have the channels stored in B G R order.

 

      cvNameWindow函數的介紹是:

Creates a window.

C++: void namedWindow (const string& winname, int flags=WINDOW_AUTOSIZE )
Python: cv2. namedWindow (winname [, flags]) → None
C: int cvNamedWindow (const char* name, int flags=CV_WINDOW_AUTOSIZE )
Python: cv. NamedWindow (name, flags=CV_WINDOW_AUTOSIZE ) → None
Parameters:
  • name – Name of the window in the window caption that may be used as a window identifier.
  • flags

    Flags of the window. The supported flags are:

    • WINDOW_NORMAL If this is set, the user can resize the window (no constraint).
    • WINDOW_AUTOSIZE If this is set, the window size is automatically adjusted to fit the displayed image (see imshow() ), and you cannot change the window size manually.
    • WINDOW_OPENGL If this is set, the window will be created with OpenGL support.

這里列舉了三種語言的函數聲明形式,大致差別不大。這里形參表給了兩個參數,第一參數是name,即窗口名稱。第二個略微有些意思,在一般情形下是三個宏。

 

The function namedWindow creates a window that can be used as a placeholder for images and trackbars. Created windows are referred to by their names.

If a window with the same name already exists, the function does nothing.

You can call destroyWindow() or destroyAllWindows() to close the window and de-allocate any associated memory usage. For a simple program, you do not really have to call these functions because all the resources and windows of the application are closed automatically by the operating system upon exit.

Note

在這里,文檔中提的相當的清晰,窗口是以名稱作為區別的,如果窗口重名了,那后者就啥都不做。

 

Qt backend supports additional flags:

  • CV_WINDOW_NORMAL or CV_WINDOW_AUTOSIZE: CV_WINDOW_NORMAL enables you to resize the window, whereas CV_WINDOW_AUTOSIZE adjusts automatically the window size to fit the displayed image (see imshow() ), and you cannot change the window size manually.
  • CV_WINDOW_FREERATIO or CV_WINDOW_KEEPRATIO: CV_WINDOW_FREERATIO adjusts the image with no respect to its ratio, whereas CV_WINDOW_KEEPRATIO keeps the image ratio.
  • CV_GUI_NORMAL or CV_GUI_EXPANDED: CV_GUI_NORMAL is the old way to draw the window without statusbar and toolbar, whereas CV_GUI_EXPANDED is a new enhanced GUI.

By default, flags == CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO | CV_GUI_EXPANDED

還順道提及了一下Qt這方面,確實有點意思了。看來也顧及到跨平台方面了。Qt中有了一些變化,但是感覺基本沒啥。

 

cvShowImage這個函數沒啥好講的,而且手冊上幾乎一筆帶過。

我們還是得看一下cvWaitKey這個函數。其實主要看一下這兩個note

Note

This function is the only method in HighGUI that can fetch and handle events, so it needs to be called periodically for normal event processing unless HighGUI is used within an environment that takes care of event processing.

Note

The function only works if there is at least one HighGUI window created and the window is active. If there are several HighGUI windows, any of them can be active.

這個例子就這么簡單一說吧,連篇累牘的英文確實令人厭煩,但是這個手冊遠遠比我寫的文檔好太多。而且這個手冊的詳盡程度不遜色於Qt。

 

——————————————————————————————————————————我是分割線————————————————————————————————————————

下面一個程序及時AVI視頻播放了,這里的代碼完全可以套在例如RMVB這樣的格式的視頻播放,前提是這種格式在你的系統里面應當有解碼器。

 1 #include<opencv\highgui.h> 
 2 int main()
 3 {
 4 cvNamedWindow("example2",CV_WINDOW_AUTOSIZE);
 5 CvCapture*capture=cvCreateFileCapture("2.avi");
 6 IplImage* frame=0;
 7 while(1)
 8 {
 9 frame=cvQueryFrame(capture);
10 if(!frame)
11 break;
12 cvShowImage("example2",frame);
13 char c=cvWaitKey(33);
14 if(c==27)
15 break;
16 }
17 cvReleaseCapture(&capture);
18 cvDestroyWindow("example2");
19 }
20 }

這里還是要從手冊里面來說一下代碼的意思吧,畢竟這本書還是說的籠統的厲害了點。

第5行中cvCapture作為一個結構體類型,在手冊中沒有提及具體成員,這里我們引用“CvCapture是一個結構體,用來保存圖像捕獲的信息,就像一種數據類型(如 int,char等)只是存放的內容不一樣,在OpenCv中,它最大的作用就是處理視頻時(程序是按一幀一幀讀取),讓程序讀下一幀的位 置,CvCapture結構中,每獲取一幀后,這些信息都將被更新,獲取下一幀回復。 引用完,來自http://blog.csdn.net/sysstc/article/details/25126551,致謝),上面說的這些大致能夠描述這個類型的適用范圍。cvCreateFileCapture這個函數手冊中也沒有講什么。

第9行中的cvQueryFrame函數在手冊中是這樣描述的:

The methods/functions combine VideoCapture::grab() and VideoCapture::retrieve() in one call. This is the most convenient method for reading video files or capturing data from decode and return the just grabbed frame. If no frames has been grabbed (camera has been disconnected, or there are no more frames in video file), the methods return false and the functions return NULL pointer.

Note

OpenCV 1.x functions cvRetrieveFrame and cv.RetrieveFrame return image stored inside the video capturing structure. It is not allowed to modify or release the image! You can copy the frame using cvCloneImage() and then do whatever you want with the copy

13行有一個巧妙地應用。這里cvWaitKey函數的使用有兩個好處:1、起到了調節播放幀數的作用。2、起到停止播放的作用。

由於這個函數位置位於while(1)這個塊內,通過不斷加載每一幀圖片來進行電影播放,但是如果任由其加載而不進行規范,則會影響效果。

The function waitKey waits for a key event infinitely (when delay<0 ) or for delay milliseconds, when it is positive. Since the OS has a minimum time between switching threads, the function will not wait exactly delay ms, it will wait at least delay ms, depending on what else is running on your computer at that time. It returns the code of the pressed key or -1 if no key was pressed before the specified time had elapsed.

Note

This function is the only method in HighGUI that can fetch and handle events, so it needs to be called periodically for normal event processing unless HighGUI is used within an environment that takes care of event processing.

Note

The function only works if there is at least one HighGUI window created and the window is active. If there are several HighGUI windows, any of them can be active.

 上面提及了這個是按照線程調度的時鍾來進行的。因此最少會間隔delay ms。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM