日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenCV 1.x 2.x 编程简介(矩阵/图像/视频的基本读写操作)

發(fā)布時間:2025/7/25 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV 1.x 2.x 编程简介(矩阵/图像/视频的基本读写操作) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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/archive/2010/01/26/5259060.aspx

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


目錄

  • 1一、簡介
    • 1.11、OpenCV的特點
      • 1.1.1(1) 總體描述
      • 1.1.2(2) 功能
      • 1.1.3(3) OpenCV模塊
    • 1.22、有用的學習資源
      • 1.2.1(1) 參考手冊:
      • 1.2.2(2) 網絡資源:
      • 1.2.3(3) 書籍:
      • 1.2.4(4) 視頻處理例程(在 <opencv-root>/samples/c/):
      • 1.2.5(5) 圖像處理例程 (在 <opencv-root>/samples/c/):
    • 1.33、OpenCV 命名規(guī)則
      • 1.3.1(1) 函數名:
      • 1.3.2(2) 矩陣數據類型:
      • 1.3.3(3) 圖像數據類型:
      • 1.3.4(4) 頭文件:
    • 1.44、編譯建議
      • 1.4.1(1) Linux:
      • 1.4.2(2) Windows:
    • 1.55、C++例程
  • 2二、GUI 指令
    • 2.11、窗口管理
      • 2.1.1(1) 創(chuàng)建和定位一個新窗口:
      • 2.1.2(2) 載入圖像:
      • 2.1.3(3) 顯示圖像:
      • 2.1.4(4) 關閉窗口:
      • 2.1.5(5) 改變窗口大小:
    • 2.22、輸入處理
      • 2.2.1(1) 處理鼠標事件:
      • 2.2.2(2) 處理鍵盤事件:
      • 2.2.3(3) 處理滑動條事件:
  • 3三、OpenCV的基本數據結構
    • 3.11、圖像數據結構
      • 3.1.1(1) IPL 圖像:
    • 3.22、矩陣與向量
      • 3.2.1(1) 矩陣:
      • 3.2.2(2) 一般矩陣:
      • 3.2.3(3) 標量:
    • 3.33、其它結構類型
      • 3.3.1(1) 點:
      • 3.3.2(2) 矩形框大小(以像素為精度):
      • 3.3.3(3) 矩形框的偏置和大小:
  • 4四、圖像處理
    • 4.11、圖像的內存分配與釋放
      • 4.1.1(1) 分配內存給一幅新圖像:
      • 4.1.2(2) 釋放圖像:
      • 4.1.3(3) 復制圖像:
      • 4.1.4(4) 設置/獲取感興趣區(qū)域ROI:
      • 4.1.5(5) 設置/獲取感興趣通道COI:
    • 4.22、圖像讀寫
      • 4.2.1(1) 從文件中讀入圖像:
      • 4.2.2(2) 保存圖像:
    • 4.33、訪問圖像像素
      • 4.3.1(1) 假設你要訪問第k通道、第i行、第j列的像素。
      • 4.3.2(2) 間接訪問: (通用,但效率低,可訪問任意格式的圖像)
      • 4.3.3(3) 直接訪問: (效率高,但容易出錯)
      • 4.3.4(4) 基于指針的直接訪問: (簡單高效)
      • 4.3.5(5) 基于 c++ wrapper 的直接訪問: (更簡單高效)
    • 4.44、圖像轉換
      • 4.4.1(1) 字節(jié)型圖像的灰度-彩色轉換:
      • 4.4.2(2) 彩色圖像->灰度圖像:
      • 4.4.3(3) 不同彩色空間之間的轉換:
    • 4.55、繪圖指令
      • 4.5.1(1) 繪制矩形:
      • 4.5.2(2) 繪制圓形:
      • 4.5.3(3) 繪制線段:
      • 4.5.4(4) 繪制一組線段:
      • 4.5.5(5) 繪制一組填充顏色的多邊形:
      • 4.5.6(6) 文本標注:
  • 5五、矩陣處理
    • 5.11、矩陣的內存分配與釋放
      • 5.1.1(1) 總體上:
      • 5.1.2(2) 為新矩陣分配內存:
      • 5.1.3(3) 釋放矩陣內存:
      • 5.1.4(4) 復制矩陣:
      • 5.1.5(5) 初始化矩陣:
      • 5.1.6(6) 初始化矩陣為單位矩陣:
    • 5.22、訪問矩陣元素
      • 5.2.1(1) 假設需要訪問一個2D浮點型矩陣的第(i, j)個單元.
      • 5.2.2(2) 間接訪問:
      • 5.2.3(3) 直接訪問(假設矩陣數據按4字節(jié)行對齊):
      • 5.2.4(4) 直接訪問(當數據的行對齊可能存在間隙時 possible alignment gaps):
      • 5.2.5(5) 對于初始化后的矩陣進行直接訪問:
    • 5.33、矩陣/向量運算
      • 5.3.1(1) 矩陣之間的運算:
      • 5.3.2(2) 矩陣之間的元素級運算:
      • 5.3.3(3) 向量乘積:
      • 5.3.4(4) 單一矩陣的運算:
      • 5.3.5(5) 非齊次線性方程求解:
      • 5.3.6(6) 特征值與特征向量 (矩陣為方陣):
  • 6六、視頻處理
    • 6.11、從視頻流中捕捉一幀畫面
      • 6.1.1(1) OpenCV 支持從攝像頭或視頻文件(AVI格式)中捕捉幀畫面.
      • 6.1.2(2) 初始化一個攝像頭捕捉器:
      • 6.1.3(3) 初始化一個視頻文件捕捉器:
      • 6.1.4(4) 捕捉一幀畫面:
      • 6.1.5(5) 釋放視頻流捕捉器:
    • 6.22、獲取/設置視頻流信息
      • 6.2.1(1) 獲取視頻流設備信息:
      • 6.2.2(2) 獲取幀圖信息:
      • 6.2.3(3) 設置從視頻文件抓取的第一幀畫面的位置:
    • 6.33、保存視頻文件
      • 6.3.1(1) 初始化視頻編寫器:
      • 6.3.2(2) 保存視頻文件:
      • 6.3.3(3) 釋放視頻編寫器:


一、簡介


1、OpenCV的特點


(1) 總體描述

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

(2) 功能

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

(3) OpenCV模塊

  • cv – 核心函數庫
  • cvaux – 輔助函數庫
  • cxcore – 數據結構與線性代數庫
  • highgui – GUI函數庫 graphical user interface
  • ml – 機器學習函數庫 machine learing

2、有用的學習資源


(1) 參考手冊:

  • <opencv-root>/docs/index.htm (譯注:在你的OpenCV安裝目錄<opencv-root>內)

(2) 網絡資源:

  • 官方網站: http://www.intel.com/technology/computing/opencv/
  • 軟件下載: http://sourceforge.net/projects/opencvlibrary/

(3) 書籍:

  • Open Source Computer Vision Library

by Gary R. Bradski, Vadim Pisarevsky, and Jean-Yves Bouguet, Springer, 1st ed. (June, 2006). chenyusiyuan: 補充以下書籍

  • Learning OpenCV - Computer Vision with the OpenCV Library

by Gary Bradski & Adrian Kaehler, O'Reilly Media, 1 st ed. (September, 2008).

  • OpenCV教程——基礎篇

作者:劉瑞禎 于仕琪,北京航空航天大學出版社,出版日期:200706


(4) 視頻處理例程(在 <opencv-root>/samples/c/):

  • 顏色跟蹤: camshiftdemo
  • 點跟蹤: lkdemo
  • 動作分割: motempl
  • 邊緣檢測: laplace

(5) 圖像處理例程 (在 <opencv-root>/samples/c/):

  • 邊緣檢測: edge
  • 圖像分割: pyramid_segmentation
  • 形態(tài)學: morphology
  • 直方圖: demhist
  • 距離變換: distrans
  • 橢圓擬合: fitellipse

3、OpenCV 命名規(guī)則

(1) 函數名:
??? cvActionTargetMod(...)

??? Action = 核心功能(core functionality) (e.g. set, create)
??? Target = 目標圖像區(qū)域(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

??? 其中

??? /usr/local/include/opencv 為opencv頭文件目錄.
??? /usr/local/lib為庫文件目錄
??? -lcv -lhighgui -lcvaux為鏈接庫文件參數.

??? 不同linxu發(fā)行版庫文件路徑可能會有所不同,x86_64版本與i386版本路徑也可能有所區(qū)別
??? 例如fedora 17 x86_64下該命令為:

??? g++? hello-world.cpp -o hello-world? \
??? -I /usr/include/opencv \
??? -L /usr/lib64? \
??? -lm -lopencv_core -lopencv_highgui


(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 <image-file-name>\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);
??????? // IplImage *pDstImg = cvCreateImage(cvGetSize(img),img->depth,img->nChannels);
??????? // cvNot(img, pDstImg);
??????? 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) 創(chuàng)建和定位一個新窗口:
??? cvNamedWindow("win1", CV_WINDOW_AUTOSIZE);
??? cvMoveWindow("win1", 100, 100); // offset from the UL corner of the screen

(2) 載入圖像:
??? IplImage* img=0;
??? img=cvLoadImage(fileName, CV_LOAD_IMAGE_COLOR);
??? if(!img) printf("Could not load image file: %s\n",fileName);

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

(4) 關閉窗口:
??? cvDestroyWindow("win1");


(5) 改變窗口大小:
??? cvResizeWindow("win1",100,100); // new width/heigh in pixels


2、輸入處理
(1) 處理鼠標事件:
??? 定義一個鼠標處理程序:
??? 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

??? 注冊該事件處理程序:
??????? mouseParam=5;
??????? cvSetMouseCallback("win1",mouseHandler,&mouseParam);? //第三個參數可以設置為NULL


(2) 處理鍵盤事件:
??? 實際上對于鍵盤輸入并沒有專門的事件處理程序.
??? 按一定間隔檢測鍵盤輸入(適用于循環(huán)體中):
??? int key;
??? key=cvWaitKey(10); // wait 10ms for input

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

??? 鍵盤輸入的循環(huán)處理程序:
??? while(1){
??????? key=cvWaitKey(10);
??????? if(key==27) break;

??????? switch(key){
????????? case 'h':
??????????? ...
??????????? break;
????????? case 'i':
??????????? ...
??????????? break;
?????? }
??? }


(3) 處理滑動條事件:

??? 定義一個滑動條處理程序:
??? void trackbarHandler(int pos)
??? {
??????? printf("Trackbar position: %d\n",pos);
??? }

??? 注冊該事件處理程序:
??? int trackbarVal=25;
??? int maxVal=100;
??? cvCreateTrackbar("bar1", "win1", &trackbarVal ,maxVal , trackbarHandler);

??? 獲取當前的滑動條位置:
??? int pos = cvGetTrackbarPos("bar1","win1");

??? 設置滑動條位置:
??? 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 只能創(chuàng)建像素交錯排列式的圖像
??? |-- int? origin;??????? // 0 – 像素原點為左上角,
??? |?????????????????????? // 1 – 像素原點為左下角 (Windows bitmaps style)
??? |-- int? widthStep;???? // 相鄰行的同列點之間的字節(jié)數??? width * nChannels * depth / 8
??? |-- int? imageSize;???? // 圖像的大小(字節(jié)為單位) = height*widthStep
??? |-- struct _IplROI *roi;// 圖像的感興趣區(qū)域(ROI). ROI非空時對圖像的
??? |?????????????????????? // 處理僅限于ROI區(qū)域.
??? |-- 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;????????? // 整行長度字節(jié)數
??? |-- 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 matrix

??? CvMatND??????????????????? // N-維矩陣
??? |-- int?? type;????????? // 元素類型 (uchar,short,int,float,double) 與標志
??? |-- int?? dims;????????? // 矩陣維數
??? |-- union data;
??? |?? |-- uchar*? ptr;???? // data pointer for an unsigned char 矩陣
??? |?? |-- 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;??????????? // 元素間距(字節(jié)為單位)

??? CvSparseMat // N-維稀疏矩陣


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


(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]=20.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) 設置/獲取感興趣區(qū)域ROI:
??? void? cvSetImageROI(IplImage* image, CvRect rect);
??? void? cvResetImageROI(IplImage* image);
??? CvRect cvGetImageROI(const IplImage* image);

??? 大多數OpenCV函數都支持 ROI, region of interests,設置了ROI之后,函數對圖片的處理只會應用到ROI區(qū)域上.

(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) 間接訪問: (通用,但效率低,可訪問任意格式的圖像)

??? 對于單通道字節(jié)型圖像:
??? IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
??? CvScalar s;
??? s=cvGet2D(img,i,j); // get the (j,i) pixel value, 注意cvGet2D與cvSet2D中坐標參數的順序與其它opencv函數坐標參數順序恰好相反.本函數中i代表y軸,即height;j代表x軸,即width.
??? printf("intensity=%f\n",s.val[0]);
??? s.val[0]=111;
??? cvSet2D(img,i,j,s); // set the (j,i) pixel value

??? 對于多通道字節(jié)型/浮點型圖像:
??? IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
??? CvScalar s;
??? s=cvGet2D(img,i,j); // get the (j,i) 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 (j,i) pixel value


(3) 直接訪問: (效率高,但容易出錯)
??? 對于單通道字節(jié)型圖像:
??? IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
??? ((uchar *)(img->imageData + i*img->widthStep))[j]=111;

??? 對于多通道字節(jié)型圖像:
??? 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

??? 對于多通道浮點型圖像:
??? 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) 基于指針的直接訪問: (簡單高效)

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

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

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


(5) 基于 c++ wrapper 的直接訪問: (更簡單高效)

??? 首先定義一個 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<RgbPixelFloat>? RgbImageFloat;
??? typedef Image<unsigned char>? BwImage;
??? typedef Image<float>????????? BwImageFloat;

??? 對于單通道字節(jié)型圖像:
??? IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
??? BwImage imgA(img);
??? imgA[i][j] = 111;

??? 對于多通道字節(jié)型圖像:
??? IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
??? RgbImage? imgA(img);
??? imgA[i][j].b = 111;
??? imgA[i][j].g = 111;
??? imgA[i][j].r = 111;

??? 對于多通道浮點型圖像:
??? IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
??? RgbImageFloat imgA(img);
??? imgA[i][j].b = 111;
??? imgA[i][j].g = 111;
??? imgA[i][j].r = 111;


4、圖像轉換
(1) 字節(jié)型圖像的灰度-彩色轉換:
??? cvConvertImage(src, dst, flags=0);
??? src = float/byte grayscale/color image
??? dst = byte grayscale/color image
??? flags = CV_CVTIMG_FLIP???? (垂直翻轉圖像)
???????? CV_CVTIMG_SWAP_RB? (置換 R 和 B 通道)

(2) 彩色圖像->灰度圖像:
??? // Using the OpenCV conversion:
??? cvCvtColor(cimg,gimg,CV_BGR2GRAY); // cimg -> gimg

??? // Using a direct conversion:
??? for(i=0;i<cimg->height;i++) for(j=0;j<cimg->width;j++)
??? gimgA[i][j]= (uchar)(cimgA[i][j].b*0.114 +
?????????????????????? cimgA[i][j].g*0.587 +
?????????????????????? cimgA[i][j].r*0.299);


(3) 不同彩色空間之間的轉換:
??? cvCvtColor(src,dst,code); // src -> dst

??? code??? = CV_<X>2<Y>
??? <X>/<Y> = RGB, BGR, GRAY, HSV, YCrCb, XYZ, Lab, Luv, HLS

??? e.g.: CV_BGR2GRAY, CV_BGR2HSV, CV_BGR2Lab

5、繪圖指令
(1) 繪制矩形:
??? // 在點 (100,100) 和 (200,200) 之間繪制一矩形,邊線用紅色、寬度為 1
??? cvRectangle(img, cvPoint(100,100), cvPoint(200,200), cvScalar(0,0,255), 1);


(2) 繪制圓形:
??? // 圓心為(100,100)、半徑為20. 圓周綠色、寬度為1
??? cvCircle(img, cvPoint(100,100), 20, cvScalar(0,255,0), 1);


(3) 繪制線段:
??? // 在 (100,100) 和 (200,200) 之間、線寬為 1 的綠色線段
??? cvLine(img, cvPoint(100,100), cvPoint(200,200), cvScalar(0,255,0), 1);

(4) 繪制一組線段:
??? CvPoint? curve1[]={10,10,? 10,100,? 100,100,? 100,10};
??? CvPoint? curve2[]={30,30,? 30,130,? 130,130,? 130,30,? 150,10};
??? CvPoint* curveArr[2]={curve1, curve2};
??? int????? nCurvePts[2]={4,5};
??? int????? nCurves=2;
??? int????? isCurveClosed=1;
??? int????? lineWidth=1;

??? cvPolyLine(img,curveArr,nCurvePts,nCurves,isCurveClosed,cvScalar(0,255,255),lineWidth);

??? void cvPolyLine( CvArr* img, CvPoint** pts, int* npts, int contours, int is_closed,
????????????????????????? CvScalar color, int thickness=1, int line_type=8, int shift=0 );
??? img?????? 圖像。
??? pts?????? 折線的頂點指針數組。
??? npts???? 折線的定點個數數組。也可以認為是pts指針數組的大小
??? contours?? 折線的線段數量。
??? is_closed? 指出多邊形是否封閉。如果封閉,函數將起始點和結束點連線。
??? color???????? 折線的顏色。
??? thickness? 線條的粗細程度。
??? line_type? 線段的類型。參見cvLine。
??? shift????????? 頂點的小數點位數


(5) 繪制一組填充顏色的多邊形:
??? cvFillPoly(img,curveArr,nCurvePts,nCurves,cvScalar(0,255,255));

??? cvFillPoly用于一個單獨被多邊形輪廓所限定的區(qū)域內進行填充。函數可以填充復雜的區(qū)域,例如,有漏洞的區(qū)域和有交叉點的區(qū)域等等。
??? void cvFillPoly( CvArr* img, CvPoint** pts, int* npts, int contours,CvScalar color, int line_type=8, int shift=0 );
??? img?????????? 圖像。
??? pts?????????? 指向多邊形的數組指針。
??? npts???????? 多邊形的頂點個數的數組。
??? contours?? 組成填充區(qū)域的線段的數量。
??? color???????? 多邊形的顏色。
??? line_type? 組成多邊形的線條的類型。
??? shift????????? 頂點坐標的小數點位數。


(6) 文本標注:
??? CvFont font;
??? double hScale=1.0;
??? double vScale=1.0;
??? int??? lineWidth=1;
??? cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, hScale,vScale,0,lineWidth);

??? cvPutText (img,"My comment",cvPoint(200,400), &font, cvScalar(255,255,0));

??? 其它可用的字體類型有: CV_FONT_HERSHEY_SIMPLEX, CV_FONT_HERSHEY_PLAIN, CV_FONT_HERSHEY_DUPLEX, CV_FONT_HERSHEY_COMPLEX, CV_FONT_HERSHEY_TRIPLEX, CV_FONT_HERSHEY_COMPLEX_SMALL, CV_FONT_HERSHEY_SCRIPT_SIMPLEX, CV_FONT_HERSHEY_SCRIPT_COMPLEX,

五、矩陣處理

1、矩陣的內存分配與釋放

(1) 總體上:
??? OpenCV 使用C語言來進行矩陣操作。不過實際上有很多C++語言的替代方案可以更高效地完成。
??? 在OpenCV中向量被當做是有一個維數為1的N維矩陣.
??? 矩陣按行-行方式存儲,每行以4字節(jié)(32位)對齊.


(2) 為新矩陣分配內存:
??? CvMat* cvCreateMat(int rows, int cols, int type);

??? type: 矩陣元素類型.
??? 按CV_<bit_depth>(S|U|F)C<number_of_channels> 方式指定.? 例如: CV_8UC1 、CV_32SC2.
??? 示例:

??? CvMat* M = cvCreateMat(4,4,CV_32FC1);


(3) 釋放矩陣內存:
??? CvMat* M = cvCreateMat(4,4,CV_32FC1);
??? cvReleaseMat(&M);


(4) 復制矩陣:
??? CvMat* M1 = cvCreateMat(4,4,CV_32FC1);
??? CvMat* M2;
??? M2=cvCloneMat(M1);


(5) 初始化矩陣:
??? double a[] = { 1,? 2,? 3,? 4,
?????????????? 5,? 6,? 7,? 8,
?????????????? 9, 10, 11, 12 };
??? CvMat Ma=cvMat(3, 4, CV_64FC1, a);

??? //等價于:
??? CvMat Ma;
??? cvInitMatHeader(&Ma, 3, 4, CV_64FC1, a);


(6) 初始化矩陣為單位矩陣:
??? CvMat* M = cvCreateMat(4,4,CV_32FC1);
??? cvSetIdentity(M); // does not seem to be working properly


2、訪問矩陣元素
(1) 假設需要訪問一個2D浮點型矩陣的第(i, j)個單元.
(2) 間接訪問:
??? cvmSet(M,i,j,2.0); // Set M(i,j)
??? t = cvmGet(M,i,j); // Get M(i,j)


(3) 直接訪問(假設矩陣數據按4字節(jié)行對齊):
??? CvMat* M??? = cvCreateMat(4,4,CV_32FC1);
??? int n?????? = M->cols;
??? float *data = M->data.fl;
??? data[i*n+j] = 3.0;


(4) 直接訪問(當數據的行對齊可能存在間隙時 possible alignment gaps):
??? CvMat* M??? = cvCreateMat(4,4,CV_32FC1);
??? int?? step? = M->step/sizeof(float);
??? float *data = M->data.fl;
??? (data+i*step)[j] = 3.0;


(5) 對于初始化后的矩陣進行直接訪問:
??? double a[16];
??? CvMat Ma = cvMat(3, 4, CV_64FC1, a);
??? a[i*4+j] = 2.0; // Ma(i,j)=2.0;


3、矩陣/向量運算
(1) 矩陣之間的運算:
??? CvMat *Ma, *Mb, *Mc;
??? cvAdd(Ma, Mb, Mc);????? // Ma+Mb?? -> Mc
??? cvSub(Ma, Mb, Mc);????? // Ma-Mb?? -> Mc
??? cvMatMul(Ma, Mb, Mc);?? // Ma*Mb?? -> Mc


(2) 矩陣之間的元素級運算:
??? CvMat *Ma, *Mb, *Mc;
??? cvMul(Ma, Mb, Mc);????? // Ma.*Mb? -> Mc
??? cvDiv(Ma, Mb, Mc);????? // Ma./Mb? -> Mc
??? cvAddS(Ma, cvScalar(-10.0), Mc); // Ma.-10 -> Mc


(3) 向量乘積:
??? double va[] = {1, 2, 3};
??? double vb[] = {0, 0, 1};
??? double vc[3];

??? CvMat Va=cvMat(3, 1, CV_64FC1, va);
??? CvMat Vb=cvMat(3, 1, CV_64FC1, vb);
??? CvMat Vc=cvMat(3, 1, CV_64FC1, vc);

??? double res=cvDotProduct(&Va,&Vb); // 向量點乘:?? Va . Vb -> res
??? cvCrossProduct(&Va, &Vb, &Vc);??? // 向量叉乘:?? Va x Vb -> Vc

??? 注意在進行叉乘運算時,Va, Vb, Vc 必須是僅有3個元素的向量.

(4) 單一矩陣的運算:
??? CvMat *Ma, *Mb;
??? cvTranspose(Ma, Mb);????? // 轉置:transpose(Ma) -> Mb (注意轉置陣不能返回給Ma本身)
??? CvScalar t = cvTrace(Ma); // 跡:trace(Ma) -> t.val[0]
??? double d = cvDet(Ma);???? // 行列式:det(Ma) -> d
??? cvInvert(Ma, Mb);???????? // 逆矩陣:inv(Ma) -> Mb


(5) 非齊次線性方程求解:
??? CvMat* A? = cvCreateMat(3,3,CV_32FC1);
??? CvMat* x? = cvCreateMat(3,1,CV_32FC1);
??? CvMat* b? = cvCreateMat(3,1,CV_32FC1);
??? cvSolve(&A, &b, &x);??? // solve (Ax=b) for x


(6) 特征值與特征向量 (矩陣為方陣):
??? CvMat* A? = cvCreateMat(3,3,CV_32FC1);
??? CvMat* E? = cvCreateMat(3,3,CV_32FC1);
??? CvMat* l? = cvCreateMat(3,1,CV_32FC1);
??? cvEigenVV(A, E, l);? // l = A 的特征值(遞減順序)
??????????????????????? // E = 對應的特征向量 (行向量)

(7) 奇異值分解(SVD):====
??? CvMat* A? = cvCreateMat(3,3,CV_32FC1);
??? CvMat* U? = cvCreateMat(3,3,CV_32FC1);
??? CvMat* D? = cvCreateMat(3,3,CV_32FC1);
??? CvMat* V? = cvCreateMat(3,3,CV_32FC1);
??? cvSVD(A, D, U, V, CV_SVD_U_T|CV_SVD_V_T); // A = U D V^T

??? 標志位使矩陣U或V按轉置形式返回 (若不轉置可能運算出錯).

六、視頻處理
1、從視頻流中捕捉一幀畫面
(1) OpenCV 支持從攝像頭或視頻文件(AVI格式)中捕捉幀畫面.
(2) 初始化一個攝像頭捕捉器:
??? CvCapture* capture = cvCaptureFromCAM(0); // capture from video device #0

(3) 初始化一個視頻文件捕捉器:
??? CvCapture* capture = cvCaptureFromAVI("infile.avi");

(4) 捕捉一幀畫面:
??? IplImage* img = 0;
??? if(!cvGrabFrame(capture)){????????????? // capture a frame
??????? printf("Could not grab a frame\n\7");
??????? exit(0);
??? }
??? img=cvRetrieveFrame(capture);?????????? // retrieve the captured frame

??? 若要從多個攝像頭中同步捕捉畫面,則須首先從每個攝像頭中抓取一幀,緊接著要將被捕捉的幀畫面恢復到一個IplImage*型圖像中。(譯注:這一過程其實可以用 cvQueryFrame() 函數一步完成)

(5) 釋放視頻流捕捉器:
??? cvReleaseCapture(&capture);

??? 注意由視頻流捕捉器得到的圖像是由捕捉器分配和釋放內存的,不需要單獨對圖像進行釋放內存的操作。

2、獲取/設置視頻流信息
(1) 獲取視頻流設備信息:
??? cvQueryFrame(capture); // 在讀取視頻流信息前,要先執(zhí)行此操作
??? int frameH??? = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
??? int frameW??? = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
??? int fps?????? = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
??? int numFrames = (int) cvGetCaptureProperty(capture,? CV_CAP_PROP_FRAME_COUNT);

??? 統(tǒng)計總幀數僅對視頻文件有效,但似乎不太準確(譯注:也許OpenCV2.0中此問題已解決)

(2) 獲取幀圖信息:
??? float posMsec?? =?????? cvGetCaptureProperty(capture, CV_CAP_PROP_POS_MSEC);
??? int posFrames?? = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES);
??? float posRatio? =?????? cvGetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO);

??? 所抓取的幀的位置有三種表達方式:距離第一幀畫面的時間間隔(毫秒為單位), 或者距離第一幀畫面(序列號為0)的序列數. 第三種方式是按相對比率,第一幀的相對比率為0,最后一幀的相對比率為1. 此方式僅對讀取視頻文件時有效.

(3) 設置從視頻文件抓取的第一幀畫面的位置:
??? // start capturing from a relative position of 0.9 of a video file
??? cvSetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO, (double)0.9);

??? 注意此方法定位并不準確。

3、保存視頻文件
(1) 初始化視頻編寫器:
??? CvVideoWriter *writer = 0;
??? int isColor = 1;
??? int fps???? = 25;? // or 30
??? int frameW? = 640; // 744 for firewire cameras
??? int frameH? = 480; // 480 for firewire cameras
??? writer=cvCreateVideoWriter("out.avi",CV_FOURCC('P','I','M','1'),
?????????????????????????? fps,cvSize(frameW,frameH),isColor);

??? 其它的編碼器代號包括: CV_FOURCC('P','I','M','1') = MPEG-1 codec CV_FOURCC('M','J','P','G') = motion-jpeg codec (does not work well) CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 codec CV_FOURCC('D', 'I', 'V', '3') = MPEG-4.3 codec CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec CV_FOURCC('U', '2', '6', '3') = H263 codec CV_FOURCC('I', '2', '6', '3') = H263I codec CV_FOURCC('F', 'L', 'V', '1') = FLV1 codec 若編碼器代號為 -1,則運行時會彈出一個編碼器選擇框.

(2) 保存視頻文件:
??? IplImage* img = 0;
??? int nFrames = 50;
??? for(i=0;i<nFrames;i++){
??????? cvGrabFrame(capture);????????? // capture a frame
??????? img=cvRetrieveFrame(capture);? // retrieve the captured frame
??????? // img = cvQueryFrame(capture);
??????? cvWriteFrame(writer,img);????? // add the frame to the file
??? }

??? 要查看所抓取到的幀畫面,可以在循環(huán)中加入以下語句:

??? cvShowImage("mainWin", img);
??? key=cvWaitKey(20);?????????? // wait 20 ms

??? 注意 cvWaitKey 參數應該不小于 20 ms,否則畫面的顯示可能出錯.

(3) 釋放視頻編寫器:
??? cvReleaseVideoWriter(&writer);



By Gady Agam 2006-03-31 翻譯:chenyusiyuan 2010-1-26

《新程序員》:云原生和全面數字化實踐50位技術專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的OpenCV 1.x 2.x 编程简介(矩阵/图像/视频的基本读写操作)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产精品日韩无码 | 福利社午夜影院 | 成人爽a毛片一区二区免费 日本高清免费看 | 国产精品乱码一区二区 | 在线观看亚洲精品视频 | 最近日韩中文字幕 | 91精品在线看 | 在线国产一区二区三区 | 久草电影网站 | 777av| 国产一区二区a | 国产精品久久久久高潮 | 欧美tv | 亚洲精品大片www | 免费成人av在线播放 | 男人天堂怡红院 | 最新福利在线 | 91亚洲国产成人精品一区 | 免费看欧美黑人毛片 | 青青草精品 | 探花精品 | 香蕉视频入口 | 一级黄色片在线免费观看 | 一区二区三区视频免费视 | 国产麻豆免费观看 | 日日噜噜夜夜爽爽 | 国产美女视频一区二区 | 91看片网页版 | 午夜国产在线观看 | 亚洲欧美一 | 黑森林av导航 | 国产无套丰满白嫩对白 | 美国成人免费视频 | 欧美xxxx吸乳 | 二级黄色片| 综合激情av | 91精品一区二区三区在线观看 | av一区二区三区四区 | 亚洲一区二区三区中文字幕 | 粗大的内捧猛烈进出在线视频 | 裸尼姑熟蜜桃 | 人人干人人玩 | 性高潮网站 | 日本黄色不卡视频 | 久久久久久久久久久丰满 | 精品熟妇视频一区二区三区 | 爱爱的网站 | 欧美成人aaaaa | 在线观看日本中文字幕 | 美女啪啪一区二区 | 国产欧美久久久久久 | 免费精品无码AV片在线观看黄 | 人人干天天操 | 精品国产乱子伦一区二区 | 天天综合网在线观看 | 亚洲免费看黄 | 99热首页 | 麻豆蜜桃在线观看 | 欧美亚洲一二三区 | 天天鲁 | 国产精品久久影院 | 一区二区三区免费看 | 日韩国产欧美综合 | 夜夜嗨av禁果av粉嫩avhd | 亚洲精品88| 欧美精品18 | 最新黄色av | 亚洲精品偷拍 | 致单身男女免费观看完整版 | 豆豆色成人网 | 日本午夜视频在线观看 | 毛片网在线 | 亚洲天堂2021av | 欧美亚洲另类在线 | 男女草逼视频 | 成人免费看av | 中文字幕 人妻熟女 | 日韩免费视频 | 91色综合| 51精品 | 日本精品一二区 | 蜜臀在线一区二区三区 | 91精产国品一二三区在线观看 | 探花国产 | 欧美日韩免费一区 | 日韩精品aaa | 黄色长视频 | 碰碰97| 精品人妻aV中文字幕乱码色欲 | 天天插天天 | 国产日本在线 | 国产精品17p | 青青草视频免费观看 | 国产亚洲综合av | 青青草视频免费观看 | 美女网站在线免费观看 | 人妻va精品va欧美va | 337p粉嫩色噜噜噜大肥臀 | 日韩av激情 |