半個月前開始學習opencv 覺得電腦視覺真是個大坑啊 沒做好準備千萬別往裡踏 否則像我一樣摔得粉身碎骨。
學習的過程中寫了一些筆記,主要是根據於仕琪的 學習opencv 上一步步來的 感覺做識別和機器學習挺有意思,與諸君共勉吧 路途漫漫 還得加把勁呐。
//2013.7.12
一.函式宣告及參數含義
Mat 圖片資料類型的申明
cvNamedWindow("example") --- 建立一個叫做example的視窗
cvCreateImage(CvSize size,int depth,int channels)
size 映像的寬和高
depth 映像的位元深度 IPL_DEPTH_8U
channels 每個元素的通道數 通常是1 2 3 4
imread(filename) -- 讀入一張圖片
cvWaitKey(0); --- 一個等待使用者輸入的函數,可以用於定格輸出畫面
IplImage* --- 圖片指標,指向圖片的資料類型
cvLoadImage(filename,flag) -- flag:1 將讀入映像強制轉換為三通道彩色映像
0 將讀入映像強制轉換為單通道灰階映像
-1 讀入與寫入映像通道數想通
cvShowImage(filename,image) filename是視窗名 image是被顯示的映像
cvReleaseImage(&image) 對image變數的一個引用,用於釋放image佔用的記憶體資源
cvDestroyWindow("exmaple")-- 銷毀視窗
PS:要先釋放資源,再銷毀視窗 否則容易記憶體泄露導致系統崩潰
cvShowImage("filename",IplIamge* image) -- 在建立的視窗中顯示image指向的圖片
二.執行個體函數用途
1.對映像進行模糊處理
cvSmooth(image1,image2,CV_GAUSSIAN,int,int)
-- 使映像平滑 image1是輸入映像 image2是輸出映像 cv_gaussian用高斯濾波(一種平滑方法)
2.邊緣檢測
cvCreateTrackbar(const char* trackbar_name, const char* window_name, int* value, int count, CvTrackbarCallback on_change);
trackbar_name 被建立的trackbar名字。
window_name 視窗名字,這個視窗將為被建立trackbar的父物件。
value 整數指標,它的值將反映滑塊的位置。這個變數指定建立時的滑塊位置。
count 滑塊位置的最大值。最小值一直是0。
on_change 每次滑塊位置被改變的時候,被調用函數的指標。這個函數應該被聲明為void Foo(int); 如果沒有回呼函數,這個值可以設為NULL。
//2013.7.15更新
3.輪廓檢測
cvGetSize(const CvArr* arr); 得到二位元組的尺寸以結構體 CvSize返回
CvSize是基本的資料類型之一 表示矩陣框的大小
typedef struct CvSize{
int width; //矩形寬
int height;//矩形高
}CvSize
4.運動物體的檢測
cvNamedWindow("name",int) --- 建立視窗
cvMoveWindow("name",int,int) --- 移動視窗,使創口排列有序
cvCaptureFromCAM(-1) --- 開啟網路攝影機
//pCapture = cvCaptureFromCAM(-1) 網路攝影機指標
cvCaptureFromFile(argv[1]) --- 開啟視頻檔案
//pCapture = cvCaptureFromFile(argv[1])
//開啟視頻檔案或者檢測運動物體的時候都是通過迴圈的一幀一幀的處理映像
所以會用到函數cvQueryFrame()---從網路攝影機或者視頻檔案中抓取並返回一幀
函數定義
ipIimage* cvQueryFrame(CvCapture* capture);
cvCreateMat(int rows,int cols,int type);
type為矩陣元素類型 CV_<位元數>(S|U|F)C<通道數>
//opencv裡的色彩空間轉換函數 可以實現RGB,HSV,HSI或者灰階映像的轉換
void cvCvtColor(const CvArr* src,CvArr* dst,int code);
src 輸入的8-bit,16-bit,32-bit單精確度浮點數影像
dst 輸出的8-bit,16-bit,32-bit單精確度浮點數影像
code 色彩空間轉換模式
CV_BGR2GRAY --灰階圖 dst需要時單通道圖片
CV_BGR2HSV --從RGB到HSV
cvConvert()函數用於映像和矩陣之間的相互轉換
void cvConvert(CvMat*,IpIimage)
將IpIimage格式轉換為CvMat
因為前者的映像資料是unsigned char類型 精度範圍只有0-255
後者卻可以存放任意通道數任意格式的資料
//對灰階映像進行閥值操作得到二值映像
void CVThreshold(const CvArr* dst,double threshold,double max_value,int threshold_type);
max_value:使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值。
threshold_type:閾實值型別 threshold_type=CV_THRESH_BINARY
//計算兩個數組差的絕對值的函數
void cvAbsDiff(const CvArr* src1,CvArr*src2,CvArr* dst);
src1-原數組 src2-第二個原數組 dst-輸出數組
dst(i) = abs(src1(i) - src2(i))
//對於地區映像的處理
允許對映像的某一小部分進行操作 使用ROI(region of interest)
使用函數
cvSetImageROI(src,cvRect(x,y,width,height));
cvResetImageROI(src)取消操作
x y width height分別是圖片中的ROI地區起始點x值 y值 地區寬度及高度
//矩陣的操作
矩陣建立的一般方法
CvMat *mat = cvCreateMat(int row,int col,int* type);
對於矩陣的讀寫操作需要用到指標
例如在求矩陣和的時候
for(int row = 0;row < matrix->rows;row++)
{
float s = 0.0;
float* ptr = (float *)(matrix->data.ptr + row * matrix->step);
for(int col = 0;col < matrix->cols;col++)
s += *ptr++;
}
會用到matrix中的step來對每一行進行定位。
//7.16日更新
關於LK稀疏光流演算法的討論
1.這個演算法用於計算光流---既用於判斷兩幀之間的易於跟蹤的特徵點
適用條件:
第一 亮度恒定,目標的像素在幀間運動時外觀保持不變。灰階圖的亮度不變。
第二 時間連續且運動變化緩慢。時間變化相對映像中的運動比例要足夠小
第三 空間一致
2.cvLine(IplImage*,CvPoint,CvPoint,Cv_RGB(a,b,c),2);
此函數用於在映像中畫出易於跟蹤點的光流路徑,Cv_RGB(a,b,c)函數用於調節所畫線段中紅綠藍三通道的比率
a,b,c均為無符號字元取值範圍[0,255]
3.void cvCalcOpticalFlowPyrLK(const CvArr* imgA,const CvArr* imgB,CvArr* PyrA,CvArr* PyrB, CvPoint2D32f* featuresA,CvPoint2D32f* featuresB,int count,char* winSize,int level,char* status,
float* track_error,cvTermCriteria criteria,int flags);
前兩個參數代表初始映像和最終映像,都是八位單通道映像。
第三四個參數是申請放入兩幅輸入影像金字塔的緩衝 大小至少為 (img.width+8)*img.height/3
featuresA和featuresB分別用於存放需找運動的點和點的新位置
count是featuresA裡點的個數
level是影像金字塔的棧的層數
track_error用於刪除外觀小地區隨點運動變化劇烈的點
criteria是迭代的終止條件 CV_TERMCRIT_EPS|CV_TERMCRIT_ITER
//2013.7.19更新
在CK演算法中遇到的問題
記憶體泄露或溢出
編譯器報錯cv::Exception at memory location
在重寫了代碼之後發現,這個演算法的計算量很大,是遞迴的演算法,所以只能支援灰階圖
並且兩個圖的解析度必須想同,這對本演算法的實用性有很大的限制