OpenCV 編程簡介(矩陣/圖像/視頻的基本讀寫操作)

PS. 由于csdn博客文章長度有限制,本文有部分內容被截掉了。
在OpenCV中文網站的wiki上有可讀性更好、并且是完整的版本,歡迎瀏覽。

OpenCV Wiki :《OpenCV 編程簡介(矩陣/圖像/視頻的基本讀寫操作)》

?

Introduction to programming with OpenCV
OpenCV編程簡介

Gady Agam
Department of Computer Science
January 27, 2006
Illinois Institute of Technology

-- URL: http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv-intro.html#SECTION00040000000000000000

譯: chenyusiyuan
--?? January 26, 2010
--??? http://blog.csdn.net/chenyusiyuan

摘要:
本文旨在幫助讀者快速入門OpenCV,而無需閱讀冗長的參考手冊。掌握了OpenCV的以下基礎知識后,有需要的話再查閱相關的參考手冊。

目錄
一??? 簡介
o??? OpenCV的特點
o??? 有用的學習資源
o??? 命名規則
o??? 編譯建議
o??? 一個例程

二??? GUI命令
o??? 窗口管理
o??? 輸入處理

三?? OpenCV基本的數據結構
o??? 圖像數據結構
o??? 矩陣與向量
o??? 其它數據結構

四??? 圖像處理
o??? 內存分配與釋放
o??? 讀取和寫入圖像
o??? 訪問圖像像素
o??? 圖像轉換
o??? 繪圖指令

五??? 矩陣處理
o??? 內存分配與釋放
o??? 訪問矩陣元素
o??? 矩陣/向量運算

六??? 視頻處理
o??? 視頻的幀捕捉
o??? 幀信息的讀取與設置
o??? 保存視頻文件

=================================================
一、簡介
1、OpenCV的特點?
(1)??? 總體描述
o??? OpenCV是一個基于C/C++語言的開源圖像處理函數庫
o??? 其代碼都經過優化,可用于實時處理圖像
o??? 具有良好的可移植性
o??? 可以進行圖像/視頻載入、保存和采集的常規操作
o??? 具有低級和高級的應用程序接口(API)
o??? 提供了面向Intel IPP高效多媒體函數庫的接口,可針對你使用的Intel CPU優化代碼,提高程序性能(譯注:OpenCV 2.0版的代碼已顯著優化,無需IPP來提升性能,故2.0版不再提供IPP接口)

(2)??? 功能
o??? 圖像數據操作(內存分配與釋放,圖像復制、設定和轉換)
Image data manipulation (allocation, release, copying, setting, conversion).
o??? 圖像/視頻的輸入輸出(支持文件或攝像頭的輸入,圖像/視頻文件的輸出)
Image and video I/O (file and camera based input, image/video file output).
o??? 矩陣/向量數據操作及線性代數運算(矩陣乘積、矩陣方程求解、特征值、奇異值分解)
Matrix and vector manipulation and linear algebra routines (products, solvers, eigenvalues, SVD).
o??? 支持多種動態數據結構(鏈表、隊列、數據集、樹、圖)
Various dynamic data structures (lists, queues, sets, trees, graphs).
o??? 基本圖像處理(去噪、邊緣檢測、角點檢測、采樣與插值、色彩變換、形態學處理、直方圖、圖像金字塔結構)
Basic image processing (filtering, edge detection, corner detection, sampling and interpolation, color conversion, morphological operations, histograms, image pyramids).
o??? 結構分析(連通域/分支、輪廓處理、距離轉換、圖像矩、模板匹配、霍夫變換、多項式逼近、曲線擬合、橢圓擬合、狄勞尼三角化)
Structural analysis (connected components, contour processing, distance transform, various moments, template matching, Hough transform, polygonal approximation, line fitting, ellipse fitting, Delaunay triangulation).
o??? 攝像頭定標(尋找和跟蹤定標模式、參數定標、基本矩陣估計、單應矩陣估計、立體視覺匹配)
Camera calibration (finding and tracking calibration patterns, calibration, fundamental matrix estimation, homography estimation, stereo correspondence).
o??? 運動分析(光流、動作分割、目標跟蹤)
Motion analysis (optical flow, motion segmentation, tracking).
o??? 目標識別(特征方法、HMM模型)Object recognition (eigen-methods, HMM).
o??? 基本的GUI(顯示圖像/視頻、鍵盤/鼠標操作、滑動條)
Basic GUI (display image/video, keyboard and mouse handling, scroll-bars).
o??? 圖像標注(直線、曲線、多邊形、文本標注)
Image labeling (line, conic, polygon, text drawing)

(3)??? OpenCV模塊
o??? cv – 核心函數庫
o??? cvaux – 輔助函數庫
o??? cxcore – 數據結構與線性代數庫
o??? highgui – GUI函數庫
o??? ml – 機器學習函數庫

2、有用的學習資源
(1)??? 參考手冊:
o??? /docs/index.htm (譯注:在你的OpenCV安裝目錄內)
???? 網絡資源:
o??? 官方網站: http://www.intel.com/technology/computing/opencv/

o??? 軟件下載: http://sourceforge.net/projects/opencvlibrary/

(2)??? 書籍:
o??? Open Source Computer Vision Library
by Gary R. Bradski, Vadim Pisarevsky, and Jean-Yves Bouguet, Springer, 1st ed. (June, 2006).
chenyusiyuan: 補充以下書籍
o??? Learning OpenCV - Computer Vision with the OpenCV Library
by Gary Bradski & Adrian Kaehler, O'Reilly Media, 1 st ed. (September, 2008).
o??? OpenCV教程——基礎篇
作者:劉瑞禎 于仕琪,北京航空航天大學出版社,出版日期:200706
(3)?? 視頻處理例程(在 /samples/c/):
o??? 顏色跟蹤: camshiftdemo
o??? 點跟蹤: lkdemo
o??? 動作分割: motempl
o??? 邊緣檢測: laplace
(4)??? 圖像處理例程 (在 /samples/c/):
o??? 邊緣檢測: edge
o??? 圖像分割: pyramid_segmentation
o??? 形態學: morphology
o??? 直方圖: demhist
o??? 距離變換: distrans
o??? 橢圓擬合: fitellipse

3、OpenCV 命名規則
(1)?? 函數名:

??? cvActionTargetMod(...)

??? Action = 核心功能(core functionality) (e.g. set, create)
??? Target = 目標圖像區域(target image area) (e.g. contour, polygon)
??? Mod??? = (可選的)調整語(optional modifiers) (e.g. argument type)


(2)?? 矩陣數據類型:

??? CV_<bit_depth>(S|U|F)C<number_of_channels>

??? S = 符號整型
??? U = 無符號整型
??? F = 浮點型

??? E.g.: CV_8UC1 是指一個8位無符號整型單通道矩陣,
????????? CV_32FC2是指一個32位浮點型雙通道矩陣.

(3)??? 圖像數據類型:

??? IPL_DEPTH_<bit_depth>(S|U|F)

??? E.g.: IPL_DEPTH_8U 圖像像素數據是8位無符號整型.
????????? IPL_DEPTH_32F圖像像素數據是32位浮點型.

(4)??? 頭文件:

??? #include <cv.h>
??? #include <cvaux.h>
??? #include <highgui.h>?
??? #include <ml.h>
??? #include <cxcore.h>?? // 一般不需要,cv.h 內已包含該頭文件 4、編譯建議
(1)?? Linux:

g++ hello-world.cpp -o hello-world /
??? -I /usr/local/include/opencv -L /usr/local/lib? /
??? -lm -lcv -lhighgui -lcvaux
(2)??? Windows:
在Visual Studio的‘選項’和‘項目’中設置好OpenCV相關文件的路徑。

5、C例程


//
// hello-world.cpp
//
// 該程序從文件中讀入一幅圖像,將之反色,然后顯示出來.
//

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>

int main(int argc, char *argv[])
{
? IplImage* img = 0;
? int height,width,step,channels;
? uchar *data;
? int i,j,k;

? if(argc<2){
??? printf("Usage: main /n/7");
??? exit(0);
? }

? // load an image?
? img=cvLoadImage(argv[1]);
? if(!img){
??? printf("Could not load image file: %s/n",argv[1]);
??? exit(0);
? }

? // get the image data
? height??? = img->height;
? width???? = img->width;
? step????? = img->widthStep;
? channels? = img->nChannels;
? data????? = (uchar *)img->imageData;
? printf("Processing a %dx%d image with %d channels/n",height,width,channels);

? // create a window
? cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);
? cvMoveWindow("mainWin", 100, 100);

? // invert the image
? // 相當于 cvNot(img);
? for(i=0;i<height;i++) for(j=0;j<width;j++) for(k=0;k<channels;k++)
??? data[i*step+j*channels+k]=255-data[i*step+j*channels+k];

? // show the image
? cvShowImage("mainWin", img );

? // wait for a key
? cvWaitKey(0);

? // release the image
? cvReleaseImage(&img );
? return 0;
}


=================================================
二、GUI 指令
1、窗口管理?
(1)??? 創建和定位一個新窗口:

? cvNamedWindow("win1", CV_WINDOW_AUTOSIZE);
? cvMoveWindow("win1", 100, 100); // offset from the UL corner of the screen
(2)??? 載入圖像:

? IplImage* img=0;
? img=cvLoadImage(fileName);
? if(!img) printf("Could not load image file: %s/n",fileName);

(3)?? 顯示圖像:?
?

?cvShowImage("win1",img);
該函數可以顯示彩色或灰度的字節型/浮點型圖像。字節型圖像像素值范圍為[0-255];浮點型圖像像素值范圍為[0-1]。彩色圖像的三色元素按BGR(藍-紅-綠)順序存儲。
(4)?? 關閉窗口:?
?

?cvDestroyWindow("win1");
(5)?? 改變窗口大小:

cvResizeWindow("win1",100,100); // new width/heigh in pixels2、輸入處理
(1)??? 處理鼠標事件:
o??? 定義一個鼠標處理程序:

void mouseHandler(int event, int x, int y, int flags, void* param)
? {
??? switch(event){
????? case CV_EVENT_LBUTTONDOWN:
??????? if(flags & CV_EVENT_FLAG_CTRLKEY)
????????? printf("Left button down with CTRL pressed/n");
??????? break;

????? case CV_EVENT_LBUTTONUP:
??????? printf("Left button up/n");
??????? break;
??? }
? }??
? x,y:?? 相對于左上角的像素坐標

? event: CV_EVENT_LBUTTONDOWN,?? CV_EVENT_RBUTTONDOWN,?? CV_EVENT_MBUTTONDOWN,
???????? CV_EVENT_LBUTTONUP,???? CV_EVENT_RBUTTONUP,???? CV_EVENT_MBUTTONUP,
???????? CV_EVENT_LBUTTONDBLCLK, CV_EVENT_RBUTTONDBLCLK, CV_EVENT_MBUTTONDBLCLK,
???????? CV_EVENT_MOUSEMOVE:

? flags: CV_EVENT_FLAG_CTRLKEY, CV_EVENT_FLAG_SHIFTKEY, CV_EVENT_FLAG_ALTKEY,
???????? CV_EVENT_FLAG_LBUTTON, CV_EVENT_FLAG_RBUTTON,? CV_EVENT_FLAG_MBUTTON
o??? 注冊該事件處理程序:?
?

mouseParam=5;
? cvSetMouseCallback("win1",mouseHandler,&mouseParam);
(2)??? 處理鍵盤事件:
o??? 實際上對于鍵盤輸入并沒有專門的事件處理程序.
o??? 按一定間隔檢測鍵盤輸入(適用于循環體中):?
?

?int key;
? key=cvWaitKey(10); // wait 10ms for input
o??? 中止程序等待鍵盤輸入:?
?

?int key;
? key=cvWaitKey(0); // wait indefinitely for input
o??? 鍵盤輸入的循環處理程序:

while(1){
??? key=cvWaitKey(10);
??? if(key==27) break;

??? switch(key){
????? case 'h':
??????? ...
??????? break;
????? case 'i':
??????? ...
??????? break;
??? }
? }?
(3)??? 處理滑動條事件:
o??? 定義一個滑動條處理程序:?
?

void trackbarHandler(int pos)
? {
??? printf("Trackbar position: %d/n",pos);
? }
o??? 注冊該事件處理程序:?
?

?int trackbarVal=25;
? int maxVal=100;
? cvCreateTrackbar("bar1", "win1", &trackbarVal ,maxVal , trackbarHandler);
o??? 獲取當前的滑動條位置:?
?

int pos = cvGetTrackbarPos("bar1","win1");
o??? 設置滑動條位置:?
??

cvSetTrackbarPos("bar1", "win1", 25);=================================================
三、OpenCV的基本數據結構
(譯注:OpenCV 1.1、1.2或2.0版本中各數據結構的結構體元素有所調整,以下僅作參考)
1、圖像數據結構
(1)??? IPL 圖像:

IplImage
? |-- int? nChannels;???? // 顏色通道數目 (1,2,3,4)
? |-- int? depth;???????? // 像素的位深:
? |?????????????????????? //?? IPL_DEPTH_8U, IPL_DEPTH_8S,
? |?????????????????????? //?? IPL_DEPTH_16U,IPL_DEPTH_16S,
? |?????????????????????? //?? IPL_DEPTH_32S,IPL_DEPTH_32F,
? |?????????????????????? //?? IPL_DEPTH_64F
? |-- int? width;???????? // 圖像寬度(像素為單位)
? |-- int? height;??????? // 圖像高度
? |-- char* imageData;??? // 圖像數據指針
? |?????????????????????? // 注意彩色圖像按BGR順序存儲數據
? |-- int? dataOrder;???? // 0 - 將像素點不同通道的值交錯排在一起,形成單一像素平面
? |?????????????????????? // 1 - 把所有像素同通道值排在一起,形成若干個通道平面,再把平面排列起來
? |?????????????????????? // cvCreateImage 只能創建像素交錯排列式的圖像
? |-- int? origin;??????? // 0 – 像素原點為左上角,
? |?????????????????????? // 1 – 像素原點為左下角 (Windows bitmaps style)
? |-- int? widthStep;???? // 相鄰行的同列點之間的字節數
? |-- int? imageSize;???? // 圖像的大小(字節為單位) = height*widthStep
? |-- struct _IplROI *roi;// 圖像的感興趣區域(ROI). ROI非空時對圖像的
? |?????????????????????? // 處理僅限于ROI區域.
? |-- char *imageDataOrigin; // 圖像數據未對齊時的數據原點指針
? |????????????????????????? // (需要正確地重新分配圖像內存 )
? |????????????????????????? // (needed for correct image deallocation)
? |-- int? align;???????? // 圖像數據的行對齊: 4 or 8 byte alignment
? |?????????????????????? // OpenCV 中無此項,采用widthStep代替
? |-- char colorModel[4]; // 顏色模型 – OpenCV中忽略此項
2、矩陣與向量
(1)??? 矩陣:

CvMat????????????????????? // 2D 矩陣
? |-- int?? type;????????? // 元素類型 (uchar,short,int,float,double) 與標志
? |-- int?? step;????????? // 整行長度字節數
? |-- int?? rows, cols;??? // 行、列數
? |-- int?? height, width; // 矩陣高度、寬度,與rows、cols對應
? |-- union data;
????? |-- uchar*? ptr;???? // data pointer for an unsigned char matrix
????? |-- short*? s;?????? // data pointer for a short matrix
????? |-- int*??? i;?????? // data pointer for an integer matrix
????? |-- float*? fl;????? // data pointer for a float matrix
????? |-- double* db;????? // data pointer for a double matrixCvMatND??????????????????? // N-維矩陣
? |-- int?? type;????????? // 元素類型 (uchar,short,int,float,double) 與標志
? |-- int?? dims;????????? // 矩陣維數
? |-- union data;
? |?? |-- uchar*? ptr;???? // data pointer for an unsigned char matrix
? |?? |-- short*? s;?????? // data pointer for a short matrix
? |?? |-- int*??? i;?????? // data pointer for an integer matrix
? |?? |-- float*? fl;????? // data pointer for a float matrix
? |?? |-- double* db;????? // data pointer for a double matrix
? |
? |-- struct dim[];??????? // 各維信息
????? |-- size;??????????? // 元素數目
????? |-- step;??????????? // 元素間距(字節為單位)CvSparseMat // N-維稀疏矩陣
(2)??? 一般矩陣:

CvArr*???? // 僅作為函數定義的參數使用,
?????????? // 表明函數可以接受不同類型的矩陣作為參數,
?????????? // 例如:IplImage*, CvMat* 甚至是 CvSeq*.
?????????? // 矩陣的類型通過矩陣頭的前4個字節信息來確定
(3)??? 標量:

CvScalar
? |-- double val[4]; //4D 向量
初始化函數:

CvScalar s = cvScalar(double val0, double val1=0, double val2=0, double val3=0);
// Example:
CvScalar s = cvScalar(20.0);
s.val[0]=10.0;
注意該初始化函數的函數名與對應的結構體名稱幾乎同名,差別僅在于函數名第一個字母是小寫的,而結構體名第一個字母是大寫的。它并不是一個 C++ 構造函數。(譯注:類似的還有 cvMat 與 CvMat、cvPoint 與 CvPoint 等等)

3、其它結構類型
(1)??? 點:

CvPoint????? p = cvPoint(int x, int y);
CvPoint2D32f p = cvPoint2D32f(float x, float y);
CvPoint3D32f p = cvPoint3D32f(float x, float y, float z);E.g.:
p.x=5.0;
p.y=5.0;
(2)??? 矩形框大小(以像素為精度):

CvSize?????? r = cvSize(int width, int height);
CvSize2D32f? r = cvSize2D32f(float width, float height);
(3)??? 矩形框的偏置和大小:

CvRect?????? r = cvRect(int x, int y, int width, int height);=================================================
四、圖像處理
1、圖像的內存分配與釋放
(1)??? 分配內存給一幅新圖像:

IplImage* cvCreateImage(CvSize size, int depth, int channels);?? size:? cvSize(width,height);

? depth: 像素深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,
??? IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F, IPL_DEPTH_64F

? channels: 像素通道數. Can be 1, 2, 3 or 4.
??? 各通道是交錯排列的. 一幅彩色圖像的數據排列格式如下:
??? b0 g0 r0 b1 g1 r1 ...
示例:

// Allocate a 1-channel byte image
IplImage* img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);

// Allocate a 3-channel float image
IplImage* img2=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);


(2)??? 釋放圖像:

IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
cvReleaseImage(&img);
(3)??? 復制圖像:

IplImage* img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
IplImage* img2;
img2=cvCloneImage(img1);? // 注意通過cvCloneImage得到的圖像
????????????????????? // 也要用 cvReleaseImage 釋放,否則容易產生內存泄漏
(4)??? 設置/獲取感興趣區域ROI:

void? cvSetImageROI(IplImage* image, CvRect rect);
void? cvResetImageROI(IplImage* image);
vRect cvGetImageROI(const IplImage* image);大多數OpenCV函數都支持 ROI.
(5)??? 設置/獲取感興趣通道COI:

void cvSetImageCOI(IplImage* image, int coi); // 0=all
int cvGetImageCOI(const IplImage* image);大多數OpenCV函數不支持 COI.

2、圖像讀寫
(1)??? 從文件中讀入圖像:?
?

?IplImage* img=0;
? img=cvLoadImage(fileName);
? if(!img) printf("Could not load image file: %s/n",fileName);? 支持的圖像格式: BMP, DIB, JPEG, JPG, JPE, PNG, PBM, PGM, PPM,
?????????????????????????? SR, RAS, TIFF, TIF
OpenCV默認將讀入的圖像強制轉換為一幅三通道彩色圖像. 不過可以按以下方法修改讀入方式:?
??

img=cvLoadImage(fileName,flag);? flag: >0 將讀入的圖像強制轉換為一幅三通道彩色圖像
??????? =0 將讀入的圖像強制轉換為一幅單通道灰度圖像
??????? <0 讀入的圖像通道數與所讀入的文件相同.
(2)??? 保存圖像:?
?

?if(!cvSaveImage(outFileName,img)) printf("Could not save: %s/n", outFileName);保存的圖像格式由 outFileName 中的擴展名確定.

3、訪問圖像像素
(1)??? 假設你要訪問第k通道、第i行、第j列的像素。
(2)??? 間接訪問: (通用,但效率低,可訪問任意格式的圖像)
o??? 對于單通道字節型圖像:

IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
CvScalar s;
s=cvGet2D(img,i,j); // get the (i,j) pixel value
printf("intensity=%f/n",s.val[0]);
s.val[0]=111;
cvSet2D(img,i,j,s); // set the (i,j) pixel value
o??? 對于多通道字節型/浮點型圖像:

IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
CvScalar s;
s=cvGet2D(img,i,j); // get the (i,j) pixel value
printf("B=%f, G=%f, R=%f/n",s.val[0],s.val[1],s.val[2]);
s.val[0]=111;
s.val[1]=111;
s.val[2]=111;
cvSet2D(img,i,j,s); // set the (i,j) pixel value
(3)??? 直接訪問: (效率高,但容易出錯)
o??? 對于單通道字節型圖像:

IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
((uchar *)(img->imageData + i*img->widthStep))[j]=111;

o??? 對于多通道字節型圖像:

IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B
((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G
((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R
o??? 對于多通道浮點型圖像:

IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R
(4)??? 基于指針的直接訪問: (簡單高效)
o??? 對于單通道字節型圖像:

IplImage* img? = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
int height???? = img->height;
int width????? = img->width;
int step?????? = img->widthStep/sizeof(uchar);
uchar* data??? = (uchar *)img->imageData;
data[i*step+j] = 111;
o??? 對于多通道字節型圖像:

IplImage* img? = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
int height???? = img->height;
int width????? = img->width;
int step?????? = img->widthStep/sizeof(uchar);
int channels?? = img->nChannels;
uchar* data??? = (uchar *)img->imageData;
data[i*step+j*channels+k] = 111;
o??? 對于多通道浮點型圖像(假設圖像數據采用4字節(32位)行對齊方式):

IplImage* img? = cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
int height???? = img->height;
int width????? = img->width;
int step?????? = img->widthStep/sizeof(float);
int channels?? = img->nChannels;
float * data??? = (float *)img->imageData;
data[i*step+j*channels+k] = 111;
(5)??? 基于 c++ wrapper 的直接訪問: (更簡單高效)
o??? 首先定義一個 c++ wrapper ‘Image’,然后基于Image定義不同類型的圖像:

template<class T> class Image
{
? private:
? IplImage* imgp;
? public:
? Image(IplImage* img=0) {imgp=img;}
? ~Image(){imgp=0;}
? void operator=(IplImage* img) {imgp=img;}
? inline T* operator[](const int rowIndx) {
??? return ((T *)(imgp->imageData + rowIndx*imgp->widthStep));}
};

typedef struct{
? unsigned char b,g,r;
} RgbPixel;

typedef struct{
? float b,g,r;
} RgbPixelFloat;

typedef Image<RgbPixel>?????? RgbImage;
typedef Image



obj格式簡介

我們經常見到的*.obj文件有兩種:第一種是基于COFF(Common Object File Format)格式的OBJ文件(也稱目標文件),這種格式用于編譯應用程序;第二種是Alias|Wavefront公司推出的OBJ模型文件。我要講的OBJ文件格式是指第二種-OBJ模型文件。  說起3D文件格式,大家一定不會感到陌生,"*.3ds","*.max","*.lw","*.mb","*.dxf","*.obj",相信人人都能列舉出幾種來。但是說起OBJ文件的具體特征,卻很少有人能給出較為圓滿的描述。 很多人認識OBJ文件是從使用Poser開始的,Poser是一款人體建模軟件,要把Poser生成的人體導出到其它3D軟件中進行再加工,就用到了OBJ文件。OBJ文件是一種標準的3D模型文件格式,很適合用于3D軟件模型之間的互導。比如你在3dsMax或LightWave中建了一個模型,想把它調到Maya里面渲染或動畫,導出OBJ文件就是一種很好的選擇。目前幾乎所有知名的3D軟件都支持OBJ文件的讀寫,不過很多軟件需要通過插件才能做到這一點。

另外,作為一種優秀的文件格式,很多游戲引擎也都支持OBJ文件的讀取。 了解OBJ文件格式有什么用呢?如果你不學編程的話,用處確實不大。不過,3D軟件模型之間的互導是一件很常見的事情,不幸的是,目前的3D軟件模型導出功能都不那么完美,經常會出現缺面少線的情況,有時還會遇到導出的模型根本打不開的情況。如果情況非常緊急的話,你一定會不惜一切代價仔細研究,期望找到原因,解決問題。在這種情況下,我的教程也許會對你有很大幫助

OBJ文件是一種文本文件格式,這就意味著你可以直接用寫字板打開進行查看修改,如果你能看懂每一行的內容是什么意思,相信距離你成功的解決問題已經不遠了。

OBJ文件是Wavefront公司為它的一套基于工作站的3D建模和動畫軟件"Advanced Visualizer"開發的一種文件格式。

  OBJ新版本是v3.0,代替以前的v2.11版本。

  OBJ3.0格式支持多邊形(Polygon),直線(Lines),表面(Surfaces),和自由形態曲線(Free-form Curves)。

直線和多角形通過它們的點來描述,曲線和表面則根據于它們的控制點和依附于曲線類型的額外信息來定義。這些信息支持規則和不規則的曲線,包括那些基于貝塞爾(Bezier)曲線,B樣條(B-spline),基數(Cardinal/Catmull-Rom樣條),和泰勒方程(Taylor equations)的曲線。

   OBJ文件 — 特點

  (1)OBJ是一種3D模型文件,因此不包含動畫、材質特性、貼圖路徑、動力學、粒子等信息。

  (2)OBJ文件主要支持多邊形(Polygons)模型。

  (3)OBJ文件支持三個點以上的面。

(4)OBJ文件支持法線和貼圖坐標。

OBJ文件不支持有孔的多邊形面

OBJ文件不包含面的顏色定義信息,不過可以引用材質庫,材質庫信息儲存在一個后綴是".mtl"的獨立文件中。關鍵字"mtllib"即材質庫的意思。材質庫中包含材質的漫射(diffuse),環境(ambient),光澤(specular)的定義值,   "usemtl"指定了材質之后,以后的面都是使用這一材質,直到遇到下一個"usemtl"來指定新的材質。

OBJ文件 — 基本結構

OBJ文件由一行行文本組成,注釋行以一個“井”號(#)為開頭,空格和空行可以隨意加到文件中以增加文件的可讀性。有字的行都由一兩個標記字母也就是關鍵字(Keyword)開頭,關鍵字可以說明這一行是什么樣的數據。多行可以邏輯地連接在一起表示一行,方法是在每一行最后添加一個連接符(/)。

注意連接符(/)后面不能出現空格或tab格,否則將導致文件出錯。

  下列關鍵字可以在OBJ文件使用。

  在這個列表中, 關鍵字根據數據類型排列,每個關鍵字有一段簡短描述。

  頂點數據(Vertex data):

   v 幾何體頂點 (Geometric vertices)

  vt 貼圖坐標點 (Texture vertices)

  vn 頂點法線 (Vertex normals)

  vp 參數空格頂點 (Parameter space vertices)

  自由形態曲線(Free-form curve)/表面屬性(surface attributes):

  deg 度 (Degree)

  bmat 基礎矩陣 (Basis matrix)

  step 步尺寸 (Step size)

  cstype 曲線或表面類型 (Curve or surface type)

  元素(Elements):

  p 點 (Point)

  l 線 (Line)

  f 面 (Face)

  curv 曲線 (Curve)

  curv2 2D曲線 (2D curve)

  surf 表面 (Surface)

  自由形態曲線(Free-form curve)/表面主體陳述(surface body statements):

  parm 參數值 (Parameter values )

  trim 外部修剪循環 (Outer trimming loop)

  hole 內部整修循環 (Inner trimming loop)

  scrv 特殊曲線 (Special curve)

  sp 特殊的點 (Special point)

  end 結束陳述 (End statement)

  自由形態表面之間的連接(Connectivity between free-form surfaces):

  con 連接 (Connect)

-  成組(Grouping):

   g 組名稱 (Group name)

  s 光滑組 (Smoothing group)

  mg 合并組 (Merging group)

  o 對象名稱 (Object name)

-  顯示(Display)/渲染屬性(render attributes):

bevel 導角插值 (Bevel interpolation)

  c_interp 顏色插值 (Color interpolation)

  d_interp 溶解插值 (Dissolve interpolation)

  lod 細節層次 (Level of detail)

  usemtl 材質名稱 (Material name)

  mtllib 材質庫 (Material library)

  shadow_obj 投射陰影 (Shadow casting)

  trace_obj 光線跟蹤 (Ray tracing)

  ctech 曲線近似技術 (Curve approximation technique)

  stech 表面近似技術 (Surface approximation technique)


vs2008 + OpenCV-2.1.0-win32-vs2008安裝

vs2008 + OpenCV-2.1.0-win32-vs2008安裝


1. 安裝vs2008+sp1
2. 安裝opencv-2.1.0-win32-vs2008
,假設安裝目錄為c:/opencv2.1。安裝過程中注意選擇添加環境變量,把 “add it to your Current User PATH “前的復選框勾上 .
3. 為vs2008配置openvc,過程如下:
?? 工具->選項->項目和解決方案->vc++目錄,
?????? “顯示一下內容的目錄”下拉列表中選擇“包含文件”,添加條目“C:/OpenCV2.1/include/opencv”;
?????? “顯示一下內容的目錄”下拉列表中選擇“庫文件” ,添加條目“C:/OpenCV2.1/lib”;
?"顯示一下內容的目錄"下拉列表選擇“源文件”,添加條目”C:/OpenCV2.1/src/cv” ,”C:/OpenCV2.1/src/cvaux” ,”C:

/OpenCV2.1/src/cxcore” ,”C:/OpenCV2.1/src/highgui”。
??????? 點擊“確定”。
4. 為單個工程配置運行環境,如:
?? (1) 新建一個win32命令控制臺項目opencvhello
?? (2) 在解決方案資源管理器中右鍵點擊項目名稱opencvhello,選擇“屬性”,
?????? 在“配置(C)”下拉列表中選擇Debug, 然后“配置屬性”->“鏈接器”->“輸入”->附加依賴項,添加??? cxcore210d.lib

cv210d.lib highgui210d.lib
?????? 在“配置(C)”下拉列表中選擇Release, 然后“配置屬性”->“鏈接器”->“輸入”->附加依賴項,添加?? cxcore210.lib

cv210.lib highgui210.lib
?????? 中間如果提示要保存的話,就保存。最后點擊確定。
?? (3) 測試。用下列代碼代替源代碼,注意imagename中保存的是圖片的硬盤地址,程序的運行結果是顯示imagename指向的圖片。
??

/***********************************************************************
?* OpenCV 2.0 測試例程
?* 于仕琪 提供
?***********************************************************************/
?
#include "stdafx.h"
#include "highgui.h"
?
//所有的以新風格命名的函數都在 cv 命名空間中
//如果希望不要每次都輸入 cv:: ,則可使用下面語句
//using namespace cv;
?
int _tmain(int argc, _TCHAR* argv[])
{
?
??? const char* imagename = "E://OpenCV2.1//samples//c//lena.jpg";
?
?cv::Mat img = cv::imread(imagename); // Matlab風格的 cvLoadImage 函數的另一種調用
??? if(img.empty())
??? {
??????? fprintf(stderr, "Can not load image %s/n", imagename);
??????? return -1;
??? }
?
??? if( !img.data ) // 檢查是否正確載入圖像
??????? return -1;
?
?cv::namedWindow("image", CV_WINDOW_AUTOSIZE); //創建窗口
?cv::imshow("image", img); //顯示圖像
?
?cv::waitKey();
?
?return 0;
}


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453211.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453211.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453211.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

再送一波干貨,測試2000線程并發下同時查詢1000萬條數據庫表及索引優化

原文:再送一波干貨&#xff0c;測試2000線程并發下同時查詢1000萬條數據庫表及索引優化繼上篇文章《絕對干貨&#xff0c;教你4分鐘插入1000萬條數據到mysql數據庫表&#xff0c;快快進來》發布后在博客園首頁展示得到了挺多的閱讀量&#xff0c;我這篇文章就是對上篇文章的千萬…

同步機制遵循的原則

進程在并發執行時為了保證結果的可再現性&#xff0c;各進程執行序列必須加以限制以保證互斥地使用臨界資源&#xff0c;相互合作完成任務。多個相關進程在執行次序上的協調稱為進程同步。用于保證多個進程在執行次序上的協調關系的相應機制稱為進程同步機制。 所有的進程同步機…

wps html編輯表格,WPS 2017個人版演示word使用技巧(wps2017表格使用技巧)

wps2017是一款非常深受用戶喜愛的辦公軟件。在2017這個新的版本中&#xff0c;依舊繼承了它之前兼容免費、體積小、多種界面切換、云辦公等眾多優秀的功能特點&#xff0c;下面小編就來教大家wps2017的使用方式使用技巧&#xff1a;一、wps2017個人版word使用技巧技巧一&#x…

ubuntu 解決“無法獲得鎖 /var/lib/dpkg/lock -open (11:資源暫時不可用)”的方法...

在ubuntu系統的termial下&#xff0c;用apt-get install 安裝軟件的時候&#xff0c;如果在未完成下載的情況下將terminal close。此時 apt-get進程可能沒有結束。結果&#xff0c;如果再次運行apt-get install 命令安裝如今&#xff0c;可能會發生下面的提示&#xff1a;無法獲…

es Update API

2019獨角獸企業重金招聘Python工程師標準>>> es Update API 博客分類&#xff1a; 搜索引擎&#xff0c;爬蟲 The update API allows to update a document based on a script provided. The operation gets the document (collocated with the shard) from the ind…

聰明人,容易不務實

聰明人擁有很多優勢。首先&#xff0c;聰明人的邏輯強、思路靈活&#xff0c;理解事物很快&#xff0c;因而經常很有創意。聰明人本身&#xff0c;也因為經常感覺到自己「快速理解、時有創意」的特質&#xff0c;認為沒有什么事情難得倒他。漸漸的&#xff0c;在看待任何事物時…

Linux 線程占用CPU過高定位分析

今天朋友問我一個Linux程序CPU占用漲停了&#xff0c;該如何分析&#xff0c; CPU占用過高&#xff0c;模擬CPU占用過高的情況 先上一段代碼&#xff1a; 1 #include <iostream>2 #include <thread>3 #include <vector>4 5 6 int main(int argc, char **argv…

計算機二級常備知識,2020年計算機二級Office考試必備題庫資料!

考試資料在手&#xff0c;考試不用愁&#xff01;領報名界面顯示計算機二級Office通過率僅21.07%&#xff0c;很多人認為是既費腦子又費時間的考試&#xff0c;可能是方法不對&#xff0c;導致花了很多時間還是考不過&#xff0c;剛剛收到3月考的二級證書啦&#xff0c;馬上還有…

MR作業的提交監控、輸入輸出控制及特性使用

2019獨角獸企業重金招聘Python工程師標準>>> MR作業的提交監控、輸入輸出控制及特性使用 博客分類&#xff1a; hadoop 提交作業并監控 JobClient是用戶作業與JobTracker交互的主要接口&#xff0c;它提供了提交作業&#xff0c;跟蹤作業進度、訪問任務報告及logs、…

ACK和NAK

ACK 英文縮寫: ACKnowledge Character在數據通信傳輸中&#xff0c;接收站發給發送站的一種傳輸控制字符。它表示確認發來的數據已經接受無誤。 NAK 英文縮寫: Negative Acknowledgment是否定應答或者非應答的縮寫。它是一個用于數字通信中確認數據受到但是有小錯誤的信號。

http協議與web本質

當你在瀏覽器地址欄敲入“http://www.csdn.net/”&#xff0c;然后猛按回車&#xff0c;呈現在你面前的&#xff0c;將是csdn的首頁了&#xff08;這真是廢話&#xff0c;你會認為這是理所當然的&#xff09;。作為一個開發者&#xff0c;尤其是web開發人員&#xff0c;我想你有…

計算機科學與技術考研課程安排,計算機科學與技術(0812)碩士研究生培養方案(一)...

一、培養目標本專業培養掌握馬克思主義基本原理、計算機科學與技術基礎理論和系統知識&#xff0c;深入了解國內外計算機科學與技術領域新技術和新動向&#xff0c;具備熟練的編程、測試能力&#xff0c;熟練掌握1門外語并具有較強創新和實踐能力&#xff0c;能夠在計算機科學與…

Docker storage driver 選擇

2019獨角獸企業重金招聘Python工程師標準>>> Docker storage driver 選擇 博客分類&#xff1a; docker 本文的目的是說明&#xff0c;如何在生產環境中選擇Docker 的storage driver。以及對應Linux發行版本下Docker storage driver的配置方法。主要參考&#xff0c…

臨界資源和臨界區

臨界資源&#xff1a; 臨界資源是一次僅允許一個進程使用的共享資源&#xff0c;各進程采取互斥的方式實現共享的資源。 屬于臨界資源的硬件有&#xff0c;打印機&#xff0c;磁帶機等&#xff1b;軟件有消息隊列&#xff0c;變量&#xff0c;數組&#xff0c;緩…

手機網站制作html5,【怎么樣制作手機網站】如何使用dreamweavercs6建立手機網站?織夢手機WAP瀏覽模塊如何制作手機網站?如何制作html5手機頁面?...

【怎么樣制作手機網站】如何使用dreamweavercs6建立手機網站?織夢手機WAP瀏覽模塊如何制作手機網站?如何制作html5手機頁面?下面就和小編一起來看看吧!如何使用dreamweavercs6建立手機網站?制作步驟如下:1。打開DreamweaverCS6軟件&#xff0c;可以在DreamweaverCS6軟件的開…

Docker查看關聯容器的卷宗在本機的存儲位置

docker inspect -f {{.Volumes}} volume1轉載于:https://www.cnblogs.com/toSeeMyDream/p/8623430.html

《那些年啊,那些事——一個程序員的奮斗史》轉載1到7

段伏櫪&#xff0c;一個瘦小&#xff0c;矮小&#xff0c;根本和“帥”這個字粘不上任何關系的普通人。名字的來源在于其多讀了幾年書的老爹&#xff0c;總抱著有一天要出書出名乃至于名流千古的美好理想&#xff0c;但可惜現實總是給予他無情的而又現實的打擊&#xff0c;于是…

如果在docker中部署tomcat,并且部署java應用程序

2019獨角獸企業重金招聘Python工程師標準>>> 如果在docker中部署tomcat,并且部署java應用程序 博客分類&#xff1a; docker 1、先說如何在docker中部署tomcat 第一步&#xff1a;root用戶登錄在系統根目錄下創建文件夾tomcat7,命令如&#xff1a;mkdir tomcat7&…

原語

一般地&#xff0c;把系統態下執行的某些具有特定功能的程序段成為原語。原語有兩種&#xff1a;1是機器指令級的&#xff0c;其特點是執行期間不允許中斷&#xff0c;正如在物理學中的原子一樣&#xff0c;在操作系統中是一個不可分割的基本單位。2是功能型的&#xff0c;其特…