首页 > 代码库 > The basic C interface in OpenCV for imagine processing

The basic C interface in OpenCV for imagine processing

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 : EOF
code date : 2014.08.04
code file : basic_imagine_interface_demo.c
e-mail  : jasonleaster@gmail.com jasonleaster@163.com

code purpose:
	This demo is coded for someone who is a beginner with
OpenCV. If there is something wrong with my code, please touch
me 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_ANYDEPTH	imagine could be non-8 bits per channel.

		CV_LOAD_IMAGE_ANYCOLOR  imagine is read as single channel

		CV_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 imagine
	B:	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 == 5s
			During this time, nothing would happen, but after this time
			if 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;
}


运行效果: