學習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()
過擬合: 先建立樹,然後修剪