1. 程式人生 > >學習OPENCV

學習OPENCV

OpenCv中文論壇精華地址
http://www.opencv.org.cn/index.php/User:Ollydbg23
http://sivp.sourceforge.net/(sivp)
一、基礎操作
1. 資料型別 資料結構瞭解
   影象相關:cvArr  cvMat IplImage
   
   資料陣列的維數, 與資料的通道數 見P46 (76)

2. 常見的矩陣操作熟悉
   
3. 資料的儲存和讀取

4. 影象的載入和顯示

5. 視訊的操作

6. 記憶體與序列
   a. 記憶體儲存器
      CvMemStorage

      雙向連結串列  動態物件(cvSeq  cvSet)的記憶體
      cvCreateMemStorage
      cvReleaseMemStorage
      cvClearMemStorage  不返還系統
      cvMemStorageAlloc

   b. 序列
      是記憶體儲存器可以儲存的一種物件。 雙端佇列
      CvSeq
      
      方法:
      cvCreateSeq
      cvClearSeq
      cvGetSeqElem
      cvCloneSeq cvSeqSlice cvSeqRemoveSlice cvSeqInsertSlice 
      cvSeqSort 
      cvSeqSearch 
      cvSeqInvert
      cvSeqPartition
      堆疊操作   cvSeqPush cvSeqPushFront  cvSeqPop  cvSeqPopFront  cvSeqPushMulti  cvSeqPopMulti
      cvSeqInsert cvSeqRemove
      cvSetSeqBlockSize
      讀出和寫入:  CvSeqWriter結構  cvStartWriteSeq  cvStartAppendToSeq  cvEndWriteSeq  cvFlushSeqWriter
                                    CV_WRITE_SEQ_ELEM  CV_WRITE_SEQ_ELEM_VAR
                   CvSeqReader結構  cvStartReadSeq   cvGetSeqReaderPos   cvSetSeqReaderPos 
                                    CV_NEXT_SEQ_ELEM V_PREV_SEQ_ELEM CV_READ_SEQ_ELEM CV_REV_READ_SEQ_ELEM
      陣列互相轉換 cvCvtSeqToArray  cvMakeSeqHeaderForArray


二. 影象的處理
1. 影象的平滑  cvSmooth
    
   主要應用: 去除噪聲, 失真,降低影象的解析度。
   主要方法: CV_BLUR   CV_BLUR_NO_SCALE  CV_MEDIAN  CV_GAUSSIAN  CV_BILATERAL

2. 影象形態學 cvErode  cvDilate  cvMorphologyEx
   主要作用: 消除噪聲  分割等
   相關方法
   a. 腐蝕    消除噪聲斑點
   b. 膨脹    連通被噪聲、陰影分割的區域
   c. 開運算  先腐蝕後膨脹
   d. 閉運算  先膨脹後腐蝕
   e. 形態梯度 
   f. "禮貌" 
   g. "黑帽" 

3. 漫水填充演算法  cvFloodFill
   作用: 標記或者分離影象的一部分。 從輸入影象獲取掩碼區域。
   原理:  把鄰近區域所有相似點填充為種子點同樣的顏色。

4. 尺寸調整  cvResize
   ROI的影響
   
   插值方法的選擇

5. 影象金字塔  cvPyrDown  cvPyrUp  cvPyrSegmentation
   簡介:源於同一原始影象的連續降取樣獲得的一個影象的集合。
   方法:高斯影象金字塔  拉普拉斯影象金字塔
   應用:影象分割

6. 閥值化 cvThreshold  cvAdaptiveThreshold
   一般閥值化
   自適應閥值化: 針對有很強照明或反射梯度的影象,需要根據梯度進行閥值化

三、影象的變換
1. 卷積 cvFilter2D
   數學公式: z(t)=f(t)*g(t)= ∫f(m)g(t-m)dm
             h(x)=(f*g)(x)
   描述:變換的基礎
   卷積核: 參考點  核支撐
   計算方法:影象參考點 = Σ 核點*對應影象點 
    
   卷積邊界:  cvCopyMakeBorder

2. 梯度和Sobel導數  cvSobel
   導數的計算:最重要且是最基本的卷積
   注意: Sobel導數並不是真正的導數,它是離散空間的擬合。
          用大核可以對導數有更好的逼近。
   scharr濾波器: sobel運算元小核時精度低,應使用scharr濾波器。

3. 拉普拉斯變換  cvLaplace
   描述: 二階導數  二階Sobel導數
   應用:  檢測"團塊"  邊緣檢測

4. Canny運算元 cvCanny
   描述: 輪廓拼裝
   應用:  邊緣檢測

5. 霍夫變換
   應用: 在影象中尋找直線、圓等其他簡單圖形的方法。
   霍夫線變換 cvHoughLines2

   霍夫圓變換 (霍夫梯度法) cvHoughCircles

6. 重對映 cvRemap
   
7. 拉伸 收縮 扭曲 旋轉
   仿射變換  
   
     稠密仿射變換: cvWarpAffine
                   計算變換矩陣: cvGetAffineTransform  cv2DRotationMatrix
     
     稀疏仿射變換: cvTransform
                   應用於一系列孤立點的對映

   透射變換: 
     密集透射變換:  cvWarpPerspective
                   計算變換矩陣: cvGetPerspectiveTransform
     稀疏透射變換:  cvPerspectiveTransform

8. cvCartToPolar cvPolarToCart
   笛卡爾座標系和極座標系的轉換

9. LogPolar
   對數極座標變換  cvLogPolar

10. 離散傅立葉變換 DFT
    http://wenku.baidu.com/view/e3b7f0fdc8d376eeaeaa3187.html
    http://wlsyzx.yzu.edu.cn/kcwz/szxhcl/kechenneirong/jiaoan/jiaoan3.htm

    cvDFT函式(實現了FFT演算法)

    cvGetOptimalDFTSize  cvGetSubRect

    cvMulSpectrums

11. 離散餘弦變換 DCT
    實數的處理  cvDCT

12. 積分影象  cvIntegral
    作用:子區域的快速求和
    應用:人臉識別

13. 距離變換  cvDistTransform
    輸入為邊緣檢測的影象

14. 直方圖均衡化 cvEqualizeHist
    應用:影象亮度分佈比較集中, 將亮度分佈範圍拉寬
     
四、直方圖
    直方圖:資訊的一種表達方式,資料分佈的統計圖。 
            對邊緣 色彩  角  亮度等特徵的統計

    bin:區間 即豎條

1. 資料結構
   CvHistogram
   
2. 操作函式
   cvCreateHist
   cvQueryHistValue_1D
   cvGetHistValue_1D
   cvNormalizeHist
   cvThreshHist 
   cvCopyHist
   cvGetMinMaxHistValue
   cvCalcHist

   cvCompareHist  (五種比較方法: CV_COMP_CORREL CV_COMP_CHISQR CV_COMP_INTERSECT CV_COMP_BHATTACHARYYA EMD)
                  尋找相關和匹配

3. 應用
   HSV: H(色調)    S(飽和度)     V(亮度值)
   a. EMD 方法  利用直方圖的距離測量來代替直方圖的匹配策略
      光線的變化引起影象顏色值的變化
      cvCalcEMD2

   b. 反向投影(back projection)
      尋找目標 
      cvCalcBackProject()計算一個畫素是否是一個已知目標的一部分
      cvCalcBackProjectPatch()計算一塊區域是否包含已知的目標  (區域檢測器  目標檢測器)

      得到目標影象的概率值, 用cvMinMaxLoc()確定目標在影象的位置

   c. 模板匹配 cvMatchTemplate
      不是基於直方圖。通過在輸入影象上滑動影象快對實際的影象快和輸入影象進行匹配。
      
      cvNormalize

五、輪廓 cvFindContours()
   根據邊緣畫素(canny)組裝成輪廓。
   用序列的資料結構表示輪廓資訊。
   處理的影象: cvCanny()輸出影象或者 cvThreshold() cvAdaptiveThreshold()的輸出影象

   重要概念:輪廓樹
             外輪廓(c)  內輪廓(h  hole)

1. cvFindContours()
   輸入影象 8通道 二值化的影象

2. 方法
   cvFindContours
   cvStartFindContours
   cvFindNextContour
   cvSubstituteContour
   cvEndFindContour
   cvApproxChains

3. 繪製輪廓
   cvDrawContours

4. 輪廓的識別和處理
   簡化或擬合輪廓,匹配輪廓到模板
   a. 多邊形逼近
     cvApproxPoly
     cvFindDominantPoints 尋找關鍵點
   
   b. 特性概括
      長度  其他度量  輪廓矩

      長度 cvContourPerimeter() cvArcLength
      面積 cvContourArea
      邊界框 cvBoundingRect  cvMinAreaRect2
             cvMinEnclosingCircle 最小包圍圓
             cvFitEllipse2  最佳擬合圓

   c. 幾何  幾個實用函式
      cvMaxRect
      cvBoxPoints
      cvPointSeqFromMat
      cvPointPolygonTest


5. 輪廓匹配
   a. 矩
      輪廓矩:比較2個輪廓最簡單的方式

      struct CvMoments

      cvContoursMoments  輸入的是輪廓(CvSeq表示)
      cvMoments          輸入的是影象
      cvGetCentralMoment
      cvGetNormalizedCentralMoment
      cvGetHuMoments     Hu矩是中心矩和歸一化矩的線性組合

   b. cvMatchShapes 用Hu矩匹配
   
   c. 等級匹配
      輪廓樹:此處的概念和之前的不同。
      輪廓樹的建立過程。
      比較2個樹的相似度。
      cvCreateContourTree  建立輪廓樹
      cvContourFromContourTree
      cvMatchContourTrees  比較

六、影象的區域性和分割
    如何從影象中將目標或部分目標分割出來。
1. 背景減除

   快速背景建模方法:光照變化不大的室內
   codebook方法:    室內外環境,週期性運動 燈光緩慢變化(速度較慢)
   
   背景和前景

   a. 背景減除缺點
   假設:所有畫素是獨立的。
   
   亮度的變化

   b. 場景建模
   前景與背景的轉化
   新的前景-舊的前景-背景

   c. 畫素片段
    畫素在一段時間內變化。
    對這種波動建立模型。
    cvInitLineIterator
    CV_NEXT_LINE_POINT()
 
   d. 幀差
   最簡單的背景減除方法就是用一幀減去另一幀,將差別作為前景。
   cvAbsDiff

   e. 平均背景法
   適用於:背景場景不包含運動的部分,要求光線保持不變。
   cvAcc() cvAbsDiff() cvInRange()

   其他類似cvAcc()的累積函式:cvRunningAvg  cvSquareAcc  cvMultiplyAcc

   f. 高階背景建模(codebook演算法)
      http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=4648&sid=3d75687ebbd68be7b92b817ec0b10dba
      適用於:有運動目標(搖曳的樹),有光線的變化

      方法: 得到每個畫素或一組畫素的時間序列模型。(消耗大量記憶體)
      codebook(編碼本): 一個畫素現在的觀測值和先前的觀測值的比較。
      RGB空間
      YUV空間、
      HSV空間(與亮度相關)  // hue色度,saturation純度,value亮度   
    
     codebook演算法(注意 它不能處理不同模式的光)
     f.1 結構
      struct code_book
      struct ce

     f.2 方法
      update_codebook:      定時呼叫,訓練和學習  (建立codebook模型)
      clear_stale_entries: 呼叫update_codebook一段時間後,呼叫這個函式做清除操作 (清除很少使用的碼本條目)
      background_diff:      使用經驗模型在先前的背景中將前景目標的畫素分割出來

     f.3 codebook演算法操作步驟
          見P318(348 )
     
   g. 清除前景的連通部分 (學習開運算 閉運算 輪廓 好的例程)
       功能強大的在背景中去除噪聲的技術
      find_connected_components

2. 分水嶺演算法    cvWatershed
   標記影象, 根據標記來分割影象

3. 用Inpainting來修補影象 cvInpaint()
   修復影象

4. 均值漂移分割 
   cvPyrMeanShiftFiltering:   finds the peaks of color distributions over space (從空間考慮)
   cvMeanShift (運動跟蹤章節): finds the peak of a color-spatial (or other feature) distribution over time(時間考慮)

   參考影象金字塔(cvPyrUp, cvPyrDown)

5. Delaunay三角剖分和Voronoi劃分
   Delaunay三角剖分是表現三維形狀的基礎, 是連線計算機視覺與計算機圖形學的橋樑。

   opencv僅實現了二維的Delaunay三角剖分.

   二維的Delaunay三角剖分的應用: 運動場景跟蹤  目標識別  不同攝像機的場景匹配
      
      
七、運動與跟蹤
1. 跟蹤基礎
   識別: 矩  顏色直方圖
          跟蹤視覺上重要的關鍵點,而不是整個物體。
          lucas-Kanade Horn-Schunk方法 (稀疏和稠密光流)
   建模:

2. 尋找角點  cvGoodFeaturesToTrack
   關鍵點,特徵點

   一個點在兩個正交的方向都有明顯的導數。
   Harris角點: 角點位於影象二階導數的自相關矩陣有兩個最大特徵值的地方。
               同時對移動和旋轉不變

3. 亞畫素角點 cvFindCornerSubPix
   精確測量
   應用: 標定,跟蹤,三維重建

4. 不變特徵
   SIFT

5. 光流
   a. 稀疏光流
     a.1 LK演算法 cvCalcOpticalFlowLK
         感興趣點的小視窗。
         缺點: 點會移出小視窗
        a.1.1 原理
              3個假設  亮度恆定;時間連續或者運動是"小運動;空間一致
              v = - It/Ix

        a.1.2 一維光流
              前2個假設
              (迭代的方法解決假設不十分正確的情況)

        a.1.2 二維光流
              考慮第3個假設解不定方程
              
     a.2 金字塔LK演算法 cvCalcOpticalFlowPyrLK
         解決大而不連貫的運動,即不滿足小而連貫的假設
         
   b. 稠密光流
     b.1 Horm-Schunck
        cvCalcOpticalFlowHS
     b.2 塊匹配方法
        cvCalcOpticalFlowBM

6. MEAN-SHIFT  CAM-SHIFT
   a. mean-shift  cvMeanShift
   通用方法,可以跟蹤物體的運動

   b. cam-shift cvCamShift
   建立在mean-shift之上,跟蹤視訊中尺寸可能產生變換的目標
   視窗可以調整

7. 運動模板
   應用: 姿態識別
   實心輪廓的獲取

   建立模板:cvUpdateMotionHistory (需要傳入輪廓)
   計算梯度:cvCalcMotionGradient  
   分割:    cvSegmentMotion

8. 預估器
   應用:目標跟蹤
   
   分兩個階段: 預估階段  校正階段

   a. Kalman Filter

   b. Condensation Algorithm  粒子濾波(參考書 probalistic robotic)
      http://zhengjunliu360.blog.163.com/blog/static/53797102201032734617104/

八、 標定
   http://www.vision.caltech.edu/bouguetj/calib_doc/
   http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=4603
   張正友經典的論文《A Flexible New Technique for Camera Calibration》
   
   針孔模型   
   透鏡的畸變 
   標定過程: 攝像機幾何模型  透鏡的畸變模型
   單應變換   homograph transform

   2件事情: 矯正畸變效應;  
             根據獲得的影象重構三維場景

1. 攝像機模型
   針孔模型
   主點: 光軸與影象平面的交點
   cx, cy: 晶片通常不在光軸上,故引入這2個變數
   fx = F * sx  fy = F * sy
   
   x = f*(X/Z)  ---> xs = fx*(X/Z) + cx

   a. 基本投影幾何
      投影變換
      q = M*Q
      M 為(fx, fy, cx, cy)表示的攝像機內參數矩陣
      Q: 物理點
      q: 影象平面的點(用投影變換的n+1維座標表示)

      cvConvertPointsHomogenious: 齊次座標處理函式

   b. 透鏡畸變
      針孔成像光線少,且成像慢,故使用透鏡,但是會引入畸變。
 
      徑向畸變:來自透鏡的形狀。
                遠離中心,畸變越厲害,便宜的網路攝像機非常厲害。
                xc = x(1+k1*r*r+k2*r*r*r*r+k3*r*r*r*r*r*r) 注意r的影響

      切向畸變:來自整個攝像機的組裝過程;透鏡本身與影象平面不平行造成的。
                xc = x+[2*p1*y+p2*(r*r+2x*x)]

      畸變向量: k1 k2 p1 p2 k3


2. 標定 cvCalibrateCamera2
   標定方法: 攝像機對準一個有很多獨立可標識點的物體。通過旋轉和移動物體,
           在不同角度觀看這個物體,可以利用通過每個影象計算攝像機的相對位置
           和方向以及攝像機的內參數。
       
   a. 旋轉矩陣和平移向量
      攝像機座標系  物體座標系(世界座標系)  <之前的公式是建立在一個座標系的>
      Pc = R*(Po - T)
      3個旋轉+3個平移  共6個引數

      6+4個內參數 = 10 至少需要2個視角??

   b. 棋盤 cvFindChessboardCorners
      OPENCV不是使用基於3D構造物體的視場,而是使用平面物體的多個視場。
      cvFindCornerSubPix()提高精度
      cvDrawChessboardCorners
      
   c. 單應性變換 homograph transform
      
      單應性:從一個平面到另一個平面的投影對映。 (Z = 0)
              如二維平面上的點對映到攝像機成像儀上的對映。
            q = s*M*W*Q
            W = [R t] 物理變換
            M: 內參矩陣
     H = s*M*W 單應性矩陣
     關注點: 不是空間中所有的Q,而只是平面上的Q, 故使Z = 0。
     opencv 正是利用從多個視場計算多個單應性矩陣的方法來求解攝像機內參數。cvFindHomography

   d. 攝像機標定 cvCalibrateCamera2
      為攝像機內參數和畸變引數進行攝像機標定。
      d.1. 
       至少需要10幅 7X8的影象
      d.2 cvFindExtrinsicCameraParams2 只計算外引數

   
3. 矯正
  a. cvUndistort2 
  b. cvInitUndistortMap   cvRemap
  c. cvUndistortPoints

4. 標定完整程式

5. cvRodrigues2
   函式提供2種表示之間的相互轉換

   旋轉的表示方法:
   直觀的方法: 向量r表示
   簡單的方法: 旋轉矩陣R


九、投影和三維視覺


十、機器學習
http://cs229.stanford.edu/materials.html 網路資料
1. 基本概念
   目的:把資料轉換為資訊。  

1.1 訓練集和測試集
   特徵
   "聚類"演算法 "分類"演算法

    訓練集  測試集  (驗證集)
    分類器

    訓練分類器的方法

1.2 監督資料和無監督資料
    監督資料:  資料有標籤(人臉有年齡)     分類
    無監督資料: 資料無標籤                 聚類

    分類  迴歸

    無監督的聚類資料經常形成一個特徵向量供更高層的有監督的分類器使用。
   
    兩個典型的機器學習任務:  分類  聚類
    計算機視覺的兩個基本任務:識別  分割

1.3 生成模型和判別模型
    判別演算法
    產生式演算法

1.4 機器學習演算法
    Mahalanobis       (歸一化特徵的方差) 非分類和聚類演算法
    K均值             非監督的聚類方法
    樸素貝葉斯分類器  通用的分類器
    決策樹            判別分類器
    Boosting          多個判別子分類器的組合
    隨機森林          由決策樹組成的"森林"
    人臉檢測/Harr分類器   巧妙使用Boosting
    期望最大化(EM)    
    K近鄰             最簡單的分類器
    神經網路          (字元識別)
    支援向量機(SVM)   分類和遞迴

1.5 視覺中使用機器學習演算法
    (特徵)
    採集資料       www.flicker.com(圖片網站)
    給資料定標籤  (http://www.mturk.com/mturk/welcome)
    提取特徵 (直方圖 色彩 ) 處理(歸一化)
    訓練集 測試集 驗證集
    選擇分類器(計算速度  資料形式 記憶體大小)

1.6 特徵向量的重要性
    決策樹
    隨機森林

    用途:減少分類器需要考慮的特徵的個數。
    Breiman的變數重要性演算法步驟:見P536 (P506)

1.7 診斷機器學習中的問題
  Andrew Ng“Advice for Applying Machine Learning” 
 (http://www.stanford.edu/class/cs229/materials/ML-advice.pdf)
    a. 大量資料比少量資料好
    b. 好的特徵比好的演算法更重要

     選取特徵:
              最大化它們的獨立性
              最小化它們在不同環境之下的變化。
    c. 欠擬合   模型假設太嚴格
       訓練和測試都不好
    d. 過擬合   學習了噪聲等
       訓練很好  測試不好
    e. 常見問題解決  見表13-2

    f. 評價分類器的效能
       交叉驗證  自抽樣法  ROC曲線  混淆矩陣


2. ML

2.1 函式 
    save
    load  (先呼叫clear)
    clear
    train
    predict
    CvStatModel
    write
    read

2.2 train
    (行,列) =(資料樣本,特徵變數)

2.3 predict

2.4 迭代次數

3. Mahalanobis
   有些分類器(K鄰近)很難處理方差很大的資料
   cvCalcCovarMatrix  計算協方差矩陣
   cvInvert           計算逆矩陣
   cvMahalanobis

4. K-mean   cvKMeans2
   聚類演算法

   問題和解決: 方差最小

5. 樸素貝葉斯分類
   最簡單監督學習分類器

6. 二叉決策樹
   迴歸不純度
   分類不純度
   度量: 熵   吉尼係數  錯分類

   特徵的重要性  get_var_importance()
   過擬合: 先建立樹,然後修剪