標籤:des style blog http color os io 檔案
The basic C interface in OpenCV for imagine processing
Creating a Window First, we want to show an image on the screen using HighGUI. Th e function that does this for us is
cvNamedWindow(). Th e function expects a name for the new window and one flag. The name appears at the top of the window, and the name is also used as a handle for the window that can be passed to other HighGUI functions. The flag indicates if the window should autosize itself to fit an image we put into it.
Here is the full prototype:
視窗標題API
int cvNamedWindow(const char* name,int flags = CV_WINDOW_AUTOSIZE);
Notice the parameter flags . For now, the only valid options available are to set flags to 0 or to use the default setting, CV_WINDOW_AUTOSIZE . If CV_WINDOW_AUTOSIZE is set, then HighGUI resizes the window to fit the image. There after, the window will automatically resize itself if a new image is loaded into the window but cannot be resized by the user.If you don’t want autosizing, you can set this argument to 0; then users can resize the window as they wish. Once we create a window, we usually want to put something into it. But before we do that, let’s see how to get rid of the window when it is no longer needed. For this we use cvDestroyWindow() , a function whose argument is a string: the name given to the window when it was created. In OpenCV, windows are referenced by name instead of by some unfriendly (and invariably OS-dependent) “handle”. Conversion between handles
and names happens under the hood of HighGUI, so you needn’t worry about it. Having said that, some people do worry about it, and that’s OK, too. For those people,
HighGUI provides the following functions:
獲得視窗的名字
void* cvGetWindowHandle( const char* name );const char* cvGetWindowName( void* window_handle );
我不得不吐槽,這兩個API 有種先生蛋還是先生雞的糾結感啊~
To resize a window, call (not surprisingly)
cvResizeWindow() :void cvResizeWindow(const char* name, int width,int height);
Here the width and height are in pixels and give the size of the drawable part of the window (which are probably the dimensions you actually care about).
這個API是用來設定自動彈出時映像的顯示大小(不經過手動調整的),缺少的部分補透明狀
Loading an Image
Before we can display an image in our window, we’ll need to know how to load an image from disk. The function for this is cvLoadImage() :
IplImage* cvLoadImage(const char* filename , int iscolor = CV_LOAD_IMAGE_COLOR);
When opening an image, cvLoadImage() does not look at the file extension. Instead, cvLoadImage() analyzes the first few bytes of the file (aka its signature or “magic sequence”) and determines the appropriate code c using that. The second argument is color can be set to one of several values. By default, images are loaded as three-channel images with 8 bits per channel; the optional flag CV_LOAD_IMAGE_ANYDEPTH can be added to allow loading of non-8-bit images. By default, the number of channels will be three because the is color flag has the default value of CV_LOAD_IMAGE_COLOR . This means that, regardless of the number of channels in the image
file, the image will be converted to three channels if needed.
該函數並不會依據圖片格式的副檔名(比方說jpg,png來確定如何載入映像,而是根據每個檔案頭的magic number來確定,如果讀者沒有聽聞過magic number,可以去看看CASPP,裡面Linking那一節講ELF格式檔案的時候有提及magic number)
CV_LOAD_IMAGE_COLOR 把映像強制轉換成3通道的映像
CV_LOAD_IMAGE_GRAYSCALE 自動的把映像轉換成合適的單通道映像(黑白映像)
CV_LOAD_IMAGE_ANYCOLOR 將簡單的載入映像儲存的形式,不做通道轉換.
此處為個人理解,如有錯漏,望讀者大方指出。
如果要載入16通道的映像 應該把第二個參數設定為 CV_LOAD_IMAGE_COLOR | CV_LOAD_IMAGE_ANYDEPTH .
If you want both the color and depth to be loaded exactly “as is”, you could instead use the all-purpose flag CV_LOAD_IMAGE_UNCHANGED .
Note that cvLoadImage() 如果發生錯誤,運行時不會有什麼處理,函數僅僅返回一個NULL指標
The obvious complementary function to cvLoadImage() is cvSaveImage() , which takes two arguments:
儲存映像
int cvSaveImage( const char* filename, const CvArr* image);
Recall that CvArr is kind of a C-style way of creating something equivalent to a base-class in an object-oriented language;wherever you see CvArr* , you can use an IplImage* . The cvSaveImage() function will store only 8-bit single- or three-channel images for most file formats. Newer back ends for flexible image formats like PNG, TIFF or JPEG2000 allow storing 16-bit or even float formats and some allow four-channel images (BGR plus alpha) as well. The return value will be 1 if the save was successful and should be 0 if the save was not.*
Displaying Images
Now we are ready for what we really want to do, and that is to load an image and to put it into the window where we can view it and appreciate its profundity.
We do this via one simple function, cvShowImage() :
void cvShowImage(const char* name,const CvArr* image);
The first argument here is the name of the window within which we intend to draw. The second argument is the image to be drawn.
A simple image displayed with cvShowImage() Before we move on, there are a few other window-related functions you ought to know about. They are:
void cvMoveWindow( const char* name, int x, int y );void cvDestroyAllWindows( void );int cvStartWindowThread( void );
cvMoveWindow() simply moves a window on the screen so that its upper left corner is positioned at x ,y.
cvDestroyAllWindows() is a useful cleanup function that closes all of the windows and deallocates the associated memory.
On Linux and MacOS, cvStartWindowThread() tries to start a thread that updates the window automatically and handles resizing and so forth.A return value of 0 indicates that no thread could be started—for example, because there is no support for this feature in the version of OpenCV that you are using. Note that, if you do not start a separate window thread, OpenCV can react to user interface actions only when it is explicitly given time to do so (this happens when your program invokes cvWaitKey() , as described next).
WaitKey Observe that inside the while loop in our window creation example there is a new function we have not seen before: cvWaitKey() . This function causes OpenCV to wait for a specified number of milliseconds for a user key stroke. If the key is pressed within the allotted time, the function returns the key pressed;* otherwise, it returns 0.
With the construction:
while( 1 ) {if( cvWaitKey(100)==27 ) break;}
we tell OpenCV to wait 100 ms for a key stroke. If there is no key stroke, then repeat ad infinitum. If there is a key stroke and it happens to have ASCII value 27 (the Escape key), then break out of that loop. This allows our user to leisurely peruse the image before ultimately exiting the program by hitting Escape.
As long as we’re introducing cvWaitKey() , it is worth mentioning that cvWaitKey() can also be called with 0 as an argument. In this case, cvWaitKey() will wait indefinitely until a keystroke is received and then return that key. Thus, in our example we could just as easily have used cvWaitKey(0) . The difference between these two options would be more apparent if we were displaying a video, in which case we would want to take an action
(i.e., display the next frame) if the user supplied no keystroke.
接著,給出對於以上介面的測試demo
/************************************************************code writer : EOFcode date : 2014.08.04code file : basic_imagine_interface_demo.ce-mail : [email protected] [email protected]code purpose:This demo is coded for someone who is a beginner withOpenCV. If there is something wrong with my code, please touchme by e-mail. Thank you.************************************************************/#include "opencv2/highgui/highgui.hpp"#include "opencv2/highgui/highgui_c.h"#include "opencv2/imgproc/imgproc.hpp"#include "opencv2/imgproc/imgproc_c.h"#include <stdio.h>int main(int argc,char* argv[]){const char* ptr_string = "Empty Castle . L";IplImage* img = cvLoadImage(argv[1],CV_LOAD_IMAGE_GRAYSCALE);/*The first parameter is the imagine file's path.The second parameter has a lot of choices:CV_LOAD_IMAGE_COLOR(defualt)imagine 3 channels each channel with 8-bits.(regardless the channel in imagine, the imagine would be read in as 3 channel)CV_LOAD_IMAGE_ANYDEPTHimagine could be non-8 bits per channel.CV_LOAD_IMAGE_ANYCOLOR imagine is read as single channelCV_LOAD_IMAGE_UNCHANGED imagine is loaded as what it is and keep it unchange.*/printf("CV_LOAD_IMAGE_COLOR : %d\n",CV_LOAD_IMAGE_COLOR);printf("CV_LOAD_IMAGE_GRAYSCALE : %d\n",CV_LOAD_IMAGE_GRAYSCALE);printf("CV_LOAD_IMAGE_ANYDEPTH : %d\n",CV_LOAD_IMAGE_ANYDEPTH);printf("CV_LOAD_IMAGE_UNCHANGED : %d\n",CV_LOAD_IMAGE_UNCHANGED);cvNamedWindow(ptr_string,0);/*The second parameter of the function just have two choice:A:CV_WINDOW_AUTOSIZE would resize the window and fit into the size of imagineB:0 would not set the window's size fit into the size of the imagine but let the programer call 'cvResizeWindow(const char* name,int width,int height)' to resize the window*/printf("CV_WINDOW_AUTOSIZE : %d\n",CV_WINDOW_AUTOSIZE);printf("\n\n");cvResizeWindow(ptr_string,100,500);//print out as 100*500 pixel,100 is width of the imagine and 500 is the height of the imagine.cvShowImage(ptr_string,img);//Obviously, show the picture that you inputed.cvSaveImage("/home/jasonleaster/The_L.jpg",img,0);/*resave the imagine as another file. In this case ,"The L" is the new file's name.*/while(1){if(cvWaitKey(5000) == 27){/*5000 is 5000 ms == 5sDuring this time, nothing would happen, but after this timeif we press down the 'Enter' key which's ASCII is 27,the cvWaitKey return the ascii code of the key, otherwise return 0.*/break;}}//pause and let the user see the picture.cvReleaseImage(&img);//Finally, release the struture, otherwise, memory leak !return 0;}
運行效果: