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
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
方法: 得到每個像素或一組像素的時間序列模型。(消耗大量內存)
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
八、 標定
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
九、投影和三維視覺
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()
過擬合: 先建立樹,然后修剪