1. 程式人生 > >opencv API (個人筆記)

opencv API (個人筆記)

                                                                                  opencv API  (個人筆記)

注:個人筆記:最主要的是記錄一些學習中遇到的問題,知識點較碎,編輯也不優美。但持續記錄、持續更新、持續分享。有問題可以留言交流。

此文也參考一些其他資料,不再單謝,可以轉載但需表明出處。

【1】 graphcut ---> grabcut ---> onecut,發展。

【2】多用於人臉68點

特徵點提取方法。

ASM(Active Shape Model)是指主觀形狀模型,即通過形狀模型 對 目標物體進行抽象。

ASM 是一種 基於點分佈模型(Point Distribution Model, PDM)的演算法。在PDM中,外形相似的物體,例如 人臉、人手、心臟等的幾何形狀可以通過若干關鍵特徵點(landmarks)的座標依次串聯形成一個形狀向量來表示。【https://www.cnblogs.com/Anita9002/p/7094535.html】

【https://blog.csdn.net/linolzhang/article/details/55271815  https://blog.csdn.net/linolzhang/article/details/55274035  】

【https://blog.csdn.net/cbl709/article/details/46239571  https://blog.csdn.net/carson2005/article/details/8194317】

 基於ASM的人臉 通常通過 標定好的68個關鍵特徵點 來進行描述:

 ASM演算法 分為 訓練過程 和 搜尋過程

• AAM

        AAM 稱為 主動外觀模型(Active Appearance Model),AAM是在ASM的基礎上,進一步對紋理(將人臉影象變換到平均形狀 而得到的形狀無關影象)進行統計建模,並將形狀和紋理兩個統計模型進一步融合為 外觀模型。可以理解為:

        Appreance = Shape + Texture

        AAM 在對形狀和紋理特徵統一量綱後,建模和搜尋過程和ASM基本相同。

• CLM

        CLM

 是有約束的區域性模型(Constrained Local Model),它通過初始化平均臉的位置,然後讓每個平均臉上的特徵點在其鄰域位置上進行搜尋匹配來完成人臉點檢測。前面講到的ASM也屬於CLM的一種。

        CLM分別繼承 ASM和AAM的優點,在ASM的效率 與 AAM的效果之間做了平衡。拋棄了AAM的全域性紋理方法,在ASM的基礎上,通過特徵點周圍的區域性紋理Patch,提高了ASM僅僅依靠灰度 帶來的匹配問題,引用一張老掉牙的圖 說明原理。

• SDM

       SDM 全名是 Supervised Descent Method,中文叫監督下降方法。

       SDM 方法提出的背景就是為了更好的解決非線性優化問題,那麼什麼是非線性優化問題呢?非線性優化問題 就是約束條件或者目標函式是非線性的。

       學界通常使用二階導數的方法進行優化,比如牛頓法。

       非線性最優化問題 通常有 2個難點:

(1)函式(方程)可能不可微,或者引數無法估計;

(2)Hessian不正定,或者維度太高導致計算量過大;

[原始碼 stASM 2013  http://www.milbo.users.sonic.net/stasm/download.html  https://github.com/juan-cardelino/stasm]

【3】resize


/************************************************************************/
/* 
OpenCV影象縮放使用的函式是:resize
void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR )
引數含義:
InputArray src     -原影象
OutputArray dst    -輸出影象
Size dsize         -目標影象的大小
double fx=0        -在x軸上的縮放比例
double fy=0        -在y軸上的縮放比例
int interpolation  -插值方式,有以下四種方式
INTER_NN      -最近鄰插值
INTER_LINEAR  -雙線性插值 (預設使用)
INTER_AREA    -使用象素關係重取樣,當影象縮小時候,該方法可以避免波紋出現。當影象放大時,類似於 INTER_NN 方法。
INTER_CUBIC   -立方插值。
說明:dsize與fx和fy必須不能同時為零

resize(src, dst, Size(), 0.5, 0.5, interpolation);
resize(src, dst, dst.size(), 0, 0, interpolation);

*/
/************************************************************************/


resize(img, img, Size(img.cols / 2, img.rows / 2), 0, 0, INTER_LINEAR);
resize(img, img, Size(), 1.3, 0.4, INTER_LINEAR);

【4】 mat型別的影象,用cvRectangle時報錯顯示[不存在"cv::Mat"到"CvArr **"的適當轉換函式];換成rectangle()函式時正確。

Mat img; const CvArr* s=(CvArr*)&img; 上面就可以了,CvArr是Mat的虛基類,所有直接強制轉換就可以了 主要C是大寫。

【5】threshold()  和adaptiveThreshold()

 一幅影象包括目標物體、背景還有噪聲,要想從多值的數字影象中直接提取出目標物體,常用的方法就是設定一個閾值T,用T將影象的資料分成兩部分:大於T的畫素群和小於T的畫素群。這是研究灰度變換的最特殊的方法,稱為影象的二值化(Binarization)。 

(1)threshold()的本質是找到一個確定值作為閾值,處理,全域性閾值。

double cv::threshold(
	cv::InputArray src,   // 輸入影象
	cv::OutputArray dst,  // 輸出影象
	double thresh,        // 閾值
	double maxValue,      // 向上最大值
	int thresholdType     // 閾值化操作的型別 
);

閾值型別: 

 效果顯示:

(2)adaptiveThreshold() 自適應閾值化能夠根據影象不同區域亮度分佈的,改變閾值,即多個閾值。

當同一幅影象上的不同部分的具有不同亮度時。這種情況下我們需要採用自適應閾值。此時的閾值是根據影象上的每一個小區域計算與其對應的閾值。因此在同一幅影象上的不同區域採用的是不同的閾值,從而使我們能在亮度不同的情況下得到更好的結果。 

通過計算每個畫素周圍bxb大小畫素塊的加權均值並減去常量C得到。其中,b由blockSize給出,大小必須為奇數;如果使用平均的方法,則所有畫素周圍的權值相同;如果使用高斯的方法,則(x,y)周圍的畫素的權值則根據其到中心點的距離通過高斯方程得到。

void cv::adaptiveThreshold(
	cv::InputArray src,   // 輸入影象
	cv::OutputArray dst,  // 輸出影象
	double maxValue,      // 向上最大值
	int adaptiveMethod,   // 自適應方法,平均或高斯
	int thresholdType     // 閾值化型別
	int blockSize,        // 塊大小
	double C              // 常量
);

閾值型別有兩種:即cv::ADAPTIVE_THRESH_MEAN_C(平均)和cv::ADAPTIVE_THRESH_GAUSSIAN_C(高斯)。

【6】   Mat <——> IplImage

1、將Mat轉換為IplImage

//! converts header to IplImage; no data is copied     operator IplImage() const;

舉例:Mat img;

            IplImage *src;

             src=&IplImage(img);

2、將IplImage轉換為Mat

//! converts old-style IplImage to the new matrix; the data is not copied by default     Mat(const IplImage* img, bool copyData=false);

【7】OpenCV ——  畫圖 、 文字 及  屬性。可以繪製的圖形有直線、矩形、多邊形、圓、橢圓。以及一個寫文字的函式puttext

關於畫圖中的LineTypes引數(可選4,8,LINE_AA三種)。如果畫水平豎直線完全沒差別。當畫斜線時,顯示區別。具體如下:

//  三條線依次向下
	line(img_01, Point(10, 10), Point(25, 18), 0, 1, 4);
	line(img_01, Point(10, 17), Point(25, 25), 0, 1, 8);
	line(img_01, Point(10, 23), Point(25, 29), 0, 1, LINE_AA);

 

                    圖01  線型                                圖02    4鄰域                 圖03   8鄰域

看圖,LineTypes引數中的4,8,LINE_AA代表點的鄰域連線方式。4鄰域,必須此點上下左右相連;8鄰域,此點8個方向相連;LINE_AA,抗鋸齒,從圖上大約看出邊緣利用較暗畫素模糊一點,基本沒啥用。

4、8鄰域的線端點即是線的兩端;LINE_AA線兩端顏色中間顏色的是端點,淺色的那個是效果點。

LineTypes總結:三個引數是線點的鄰域連線方式,只在斜線上表現差異。一般用8鄰域即可。