很久沒有更新博客了。
今天更新一個小Demo,使用opencv,從本地讀取一張圖片。【先代碼->演示結果->分析代碼】
OpenCV 版本: opencv-3.1.0
關於環境的配置略過,大家可以搜索一下其他的教程說明。
代碼:
#include "highgui.h"
int main(int argc, char* argv[])
{
IplImage* src = cvLoadImage("01.jpg",1);//加載一張圖片
cvNamedWindow("title",1);//創建一個窗體
cvShowImage("title", src);//在上面的窗體中顯示圖片
cvWaitKey(0);//等待用戶按鍵
cvReleaseImage(&src);//釋放圖片資源
cvDestroyWindow("title");//釋放窗體資源
return 0;
}
請準備一張01.jpg圖片放在該cpp文件目錄下。
運行圖:
其中IplImage結構如下:
typedef struct _IplImage
{
int nSize; /**< sizeof(IplImage) */
int ID; /**< version (=0)*/
int nChannels; /**< Most of OpenCV functions support 1,2,3 or 4 channels */
int alphaChannel; /**< Ignored by OpenCV */
int depth; /**< Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,
IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported. */
char colorModel[4]; /**< Ignored by OpenCV */
char channelSeq[4]; /**< ditto */
int dataOrder; /**< 0 - interleaved color channels, 1 - separate color channels.
cvCreateImage can only create interleaved images */
int origin; /**< 0 - top-left origin,
1 - bottom-left origin (Windows bitmaps style). */
int align; /**< Alignment of image rows (4 or 8).
OpenCV ignores it and uses widthStep instead. */
int width; /**< Image width in pixels. */
int height; /**< Image height in pixels. */
struct _IplROI *roi; /**< Image ROI. If NULL, the whole image is selected. */
struct _IplImage *maskROI; /**< Must be NULL. */
void *imageId; /**< " " */
struct _IplTileInfo *tileInfo; /**< " " */
int imageSize; /**< Image data size in bytes
(==image->height*image->widthStep
in case of interleaved data)*/
char *imageData; /**< Pointer to aligned image data. */
int widthStep; /**< Size of aligned image row in bytes. */
int BorderMode[4]; /**< Ignored by OpenCV. */
int BorderConst[4]; /**< Ditto. */
char *imageDataOrigin; /**< Pointer to very origin of image data
(not necessarily aligned) -
needed for correct deallocation */
} IplImage;
width和height這兩個變量很重要,其次是depth和nchannals。depth變量的值取自ipl.h中定義的一組數據,但與在矩陣中看到的對應變量不同。因爲在圖像中,我們往往將深度和通道數分開處理,深度值如下表
宏 | 圖像像素類型 |
---|---|
IPL_DEPTH_8U | 無符號8位整數(8u) |
IPL_DEPTH_8S | 有符號8位整數(8s) |
IPL_DEPTH_16S | 有符號16位整數(16s) |
IPL_DEPTH_32S | 有符號32位整數(32s) |
IPL_DEPTH_32F | 32位浮點數單精度(32f) |
IPL_DEPTH_64F | 64位浮點數雙精度(64f) |
下面轉一段別人總結的深度顯示範圍。
測試double型:0.0–1.0之間 IPL_DEPTH_64F
測試float型:0.0–1.0之間 IPL_DEPTH_32F
測試long型:0–65535之間 IPL_DEPTH_32S
測試short int型:-32768–32767之間 IPL_DEPTH_16S
測試unsigned short int型:0–65535之間 IPL_DEPTH_16U
測試char型:-128–127之間 IPL_DEPTH_8S
測試unsigned char型:0–255之間 IPL_DEPTH_8U
這個時候如果需要保存圖像,請記住要先轉換到IPL_DEPTH_8U的深度。因爲只有8位單通道或者3通道(通道順序爲’BGR’)纔可以使用cvSaveImage保存。
通道數nChannels可取的值是1,2,3或4
origin: 2種值(IPL_ORIGIN_TL 或者 IPL_ORIGIN_BL)分別設置座標原點的位置於圖像的左上角(TL->top left)或者左下角(BL->bottom left)
**ROI感興趣區域**COI感興趣通道
關於加載圖片格式
cvLoadImage()寒素可以讀取大多數格式類型的圖像文件,這列類型包括BMP,DIB,JPEG,PNG,PBM,PGM,SR,RAS和TIFF。該函數執行完後將返回一個指針,此指針指向一個塊爲描述該圖像文件的數據結構(IplImage)而分配的內存塊。
關於加載顏色深度
enum
{
/* 8bit, color or not */
CV_LOAD_IMAGE_UNCHANGED =-1,
/* 8bit, gray */
CV_LOAD_IMAGE_GRAYSCALE =0,
/* ?, color */
CV_LOAD_IMAGE_COLOR =1,
/* any depth, ? */
CV_LOAD_IMAGE_ANYDEPTH =2,
/* ?, any color */
CV_LOAD_IMAGE_ANYCOLOR =4
};
使用原始加載可以這樣:
IplImage* src = cvLoadImage("01.jpg", CV_LOAD_IMAGE_ANYDEPTH || CV_LOAD_IMAGE_ANYCOLOR);
關於創建窗體
我們使用的是cvNamedWindow();函數它的定義如下:
/* create window */
cvNamedWindow( const char* name, int flags CV_DEFAULT(CV_WINDOW_AUTOSIZE) )
參數1,name:類似於窗體的ID,也是它的名稱
參數2,flags :是窗體的加載屬性,它有如下值的定義如下:
//These 2 flags are used by cvNamedWindow and cvSet/GetWindowProperty
CV_WINDOW_NORMAL = 0x00000000, //the user can resize the window (no constraint) / also use to switch a fullscreen window to a normal size
CV_WINDOW_AUTOSIZE = 0x00000001, //the user cannot resize the window, the size is constrainted by the image displayed
CV_WINDOW_OPENGL = 0x00001000, //window with opengl support
如何使用該函數?如下
cvNamedWindow("title",1);//創建一個窗體
其中數字值可以代替上面的flags定義好的宏值。
關於顯示圖片
我們使用的cvShowImage()函數,定義如下:
/* display image within window (highgui windows remember their content) */
CVAPI(void) cvShowImage( const char* name, const CvArr* image );
參數1 , name : 待顯示的窗體name
參數2,image:是要顯示的圖片資源,一個圖片數據結構,對應的需要一個IplImage*類型的指針
使用該函數,該窗口將被重新繪製。
如何使用?如下
cvShowImage("title", src);//在窗體中顯示圖片
關於釋放資源
該程序窗口所佔用的一切資源都會由操作系統自動釋放,對應簡單的程序,可不必調用函數顯示釋放資源,但是,養成習慣每次都調用這些函數顯示釋放資源總是有好處的。