轉自:http://blog.csdn.net/poem_qianmo/article/details/20537737
1:Mat?imread(const?string&?filename,?intflags=1?);?
? eg:?
- Mat?image0=imread("dota.jpg",CV_LOAD_IMAGE_ANYDEPTH?|?CV_LOAD_IMAGE_ANYCOLOR);//載入最真實的圖像??
- ge1=imread("dota.jpg",0);//載入灰度圖??
- Mat?image2=imread("dota.jpg",199);//載入3通道的彩色圖像??
- Mat?logo=imread("dota_logo.jpg");//載入3通道的彩色圖像??
- 第一個參數,const string&類型的trackbarname,表示軌跡條的名字,用來代表我們創建的軌跡條。
- 第二個參數,const string&類型的winname,填窗口的名字,表示這個軌跡條會依附到哪個窗口上,即對應namedWindow()創建窗口時填的某一個窗口名。
- 第三個參數,int* 類型的value,一個指向整型的指針,表示滑塊的位置。并且在創建時,滑塊的初始位置就是該變量當前的值。
- 第四個參數,int類型的count,表示滑塊可以達到的最大位置的值。PS:滑塊最小的位置的值始終為0。
- 第五個參數,TrackbarCallback類型的onChange,首先注意他有默認值0。這是一個指向回調函數的指針,每次滑塊位置改變時,這個函數都會進行回調。并且這個函數的原型必須為void XXXX(int,void*);其中第一個參數是軌跡條的位置,第二個參數是用戶數據(看下面的第六個參數)。如果回調是NULL指針,表示沒有回調函數的調用,僅第三個參數value有變化。
- 第六個參數,void*類型的userdata,他也有默認值0。這個參數是用戶傳給回調函數的數據,用來處理軌跡條事件。如果使用的第三個參數value實參是全局變量的話,完全可以不去管這個userdata參數。
- ******************************************************************************************************************************
- Size(5,?5);//構造出的Size寬度和高度都為5,即XXX.width和XXX.height都為5??
? ? ? ?參數詳解:
- 第一個參數,InputArray類型的src,輸入圖像,即源圖像,填Mat類的對象即可。該函數對通道是獨立處理的,且可以處理任意通道數的圖片,但需要注意,待處理的圖片深度應該為CV_8U, CV_16U, CV_16S, CV_32F 以及 CV_64F之一。
- 第二個參數,OutputArray類型的dst,即目標圖像,需要和源圖片有一樣的尺寸和類型。
- 第三個參數,int類型的ddepth,輸出圖像的深度,-1代表使用原圖深度,即src.depth()。
- 第四個參數,Size類型(對Size類型稍后有講解)的ksize,內核的大小。一般這樣寫Size( w,h )來表示內核的大小( 其中,w 為像素寬度, h為像素高度)。Size(3,3)就表示3x3的核大小,Size(5,5)就表示5x5的核大小
- 第五個參數,Point類型的anchor,表示錨點(即被平滑的那個點),注意他有默認值Point(-1,-1)。如果這個點坐標是負值的話,就表示取核的中心為錨點,所以默認值Point(-1,-1)表示這個錨點在核的中心。
- 第六個參數,bool類型的normalize,默認值為true,一個標識符,表示內核是否被其區域歸一化(normalized)了。
- 第七個參數,int類型的borderType,用于推斷圖像外部像素的某種邊界模式。有默認值BORDER_DEFAULT,我們一般不去管它
- 第一個參數,InputArray類型的src,輸入圖像,即源圖像,填Mat類的對象即可。該函數對通道是獨立處理的,且可以處理任意通道數的圖片,但需要注意,待處理的圖片深度應該為CV_8U, CV_16U, CV_16S, CV_32F 以及 CV_64F之一。
- 第二個參數,OutputArray類型的dst,即目標圖像,需要和源圖片有一樣的尺寸和類型。比如可以用Mat::Clone,以源圖片為模板,來初始化得到如假包換的目標圖。
- 第三個參數,Size類型(對Size類型稍后有講解)的ksize,內核的大小。一般這樣寫Size( w,h )來表示內核的大小( 其中,w 為像素寬度, h為像素高度)。Size(3,3)就表示3x3的核大小,Size(5,5)就表示5x5的核大小
- 第四個參數,Point類型的anchor,表示錨點(即被平滑的那個點),注意他有默認值Point(-1,-1)。如果這個點坐標是負值的話,就表示取核的中心為錨點,所以默認值Point(-1,-1)表示這個錨點在核的中心。
- 第五個參數,int類型的borderType,用于推斷圖像外部像素的某種邊界模式。有默認值BORDER_DEFAULT,我們一般不去管它
- 第一個參數,InputArray類型的src,輸入圖像,即源圖像,填Mat類的對象即可。它可以是單獨的任意通道數的圖片,但需要注意,圖片深度應該為CV_8U,CV_16U, CV_16S, CV_32F 以及 CV_64F之一。
- 第二個參數,OutputArray類型的dst,即目標圖像,需要和源圖片有一樣的尺寸和類型。比如可以用Mat::Clone,以源圖片為模板,來初始化得到如假包換的目標圖。
- 第三個參數,Size類型的ksize高斯內核的大小。其中ksize.width和ksize.height可以不同,但他們都必須為正數和奇數。或者,它們可以是零的,它們都是由sigma計算而來。
- 第四個參數,double類型的sigmaX,表示高斯核函數在X方向的的標準偏差。
- 第五個參數,double類型的sigmaY,表示高斯核函數在Y方向的的標準偏差。若sigmaY為零,就將它設為sigmaX,如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height計算出來。
- 為了結果的正確性著想,最好是把第三個參數Size,第四個參數sigmaX和第五個參數sigmaY全部指定到。
- 第六個參數,int類型的borderType,用于推斷圖像外部像素的某種邊界模式。有默認值BORDER_DEFAULT,我們一般不去管它。
? ? ? ?參數詳解:
- 第一個參數,InputArray類型的src,函數的輸入參數,填1、3或者4通道的Mat類型的圖像;當ksize為3或者5的時候,圖像深度需為CV_8U,CV_16U,或CV_32F其中之一,而對于較大孔徑尺寸的圖片,它只能是CV_8U。
- 第二個參數,OutputArray類型的dst,即目標圖像,函數的輸出參數,需要和源圖片有一樣的尺寸和類型。我們可以用Mat::Clone,以源圖片為模板,來初始化得到如假包換的目標圖。
- 第三個參數,int類型的ksize,孔徑的線性尺寸(aperture linear size),注意這個參數必須是大于1的奇數,比如:3,5,7,9 ...
- 第一個參數,InputArray類型的src,輸入圖像,即源圖像,需要為8位或者浮點型單通道、三通道的圖像。
- 第二個參數,OutputArray類型的dst,即目標圖像,需要和源圖片有一樣的尺寸和類型。
- 第三個參數,int類型的d,表示在過濾過程中每個像素鄰域的直徑。如果這個值我們設其為非正數,那么OpenCV會從第五個參數sigmaSpace來計算出它來。
- 第四個參數,double類型的sigmaColor,顏色空間濾波器的sigma值。這個參數的值越大,就表明該像素鄰域內有更寬廣的顏色會被混合到一起,產生較大的半相等顏色區域。
- 第五個參數,double類型的sigmaSpace坐標空間中濾波器的sigma值,坐標空間的標注方差。他的數值越大,意味著越遠的像素會相互影響,從而使更大的區域足夠相似的顏色獲取相同的顏色。當d>0,d指定了鄰域大小且與sigmaSpace無關。否則,d正比于sigmaSpace。
- 第六個參數,int類型的borderType,用于推斷圖像外部像素的某種邊界模式。注意它有默認值BORDER_DEFAULT。
? ? ? 膨脹與腐蝕能實現多種多樣的功能,主要如下:
- 消除噪聲
- 分割(isolate)出獨立的圖像元素,在圖像中連接(join)相鄰的元素。
- 尋找圖像中的明顯的極大值區域或極小值區域
- 求出圖像的梯度
- C++:?void?dilate(??
- ????InputArray?src,??
- ????OutputArray?dst,??
- ????InputArray?kernel,??
- ????Point?anchor=Point(-1,-1),??
- ????int?iterations=1,??
- ????int?borderType=BORDER_CONSTANT,??
- ????const?Scalar&?borderValue=morphologyDefaultBorderValue()???
- );?
? ? ? ?那么,我們接下來一起看一看拉普拉斯金字塔的概念吧
- 對圖像向上采樣:pyrUp函數(圖像尺寸加倍,圖像首先在每個維度上擴大為原來的兩倍,新增的行(偶數行)以0填充。然后給指定的濾波器進行卷積(實際上是一個在每個維度都擴大為原來兩倍的過濾器)去估計“丟失”像素的近似值。)
- 對圖像向下采樣:pyrDown函數
? ? ? ? 為了獲取層級為 G_i+1 的金字塔圖像,我們采用如下方法:
? ? ? ?<1>對圖像G_i進行高斯內核卷積
? ? ? ?<2>將所有偶數行和列去除
? ? ? ?得到的圖像即為G_i+1的圖像,顯而易見,結果圖像只有原圖的四分之一。通過對輸入圖像G_i(原始圖像)不停迭代以上步驟就會得到整個金字塔。同時我們也可以看到, ? ? ? ? ?向下取樣會逐漸丟失圖像的信息。
? ? ? ?以上就是對圖像的向下取樣操作,即縮小圖像。
?
? 8.2:?對圖像的向上取樣
? ? ? ?如果想放大圖像,則需要通過向上取樣操作得到,具體做法如下:
? ? ? <1>將圖像在每個方向擴大為原來的兩倍,新增的行和列以0填充
? ? ? <2>使用先前同樣的內核(乘以4)與放大后的圖像卷積,獲得 “新增像素”的近似值
? ? ? 得到的圖像即為放大后的圖像,但是與原來的圖像相比會發覺比較模糊,因為在縮放的過程中已經丟失了一些信息,如果想在縮小和放大整個過程中減少信息的丟失,這些 ? ? ? 數據形成了拉普拉斯金字塔。
? ? ? 那么,我們接下來一起看一看拉普拉斯金字塔的概念吧
****************************************************************************************************************************************************************************************
?9:resize函數剖析? ?void?resize(InputArray?src,OutputArray?dst,?Size?dsize,?double?fx=0,?double?fy=0,?int?interpolation=INTER_LINEAR)
- 第一個參數,InputArray類型的src,輸入圖像,即源圖像,填Mat類的對象即可。
- 第二個參數,OutputArray類型的dst,輸出圖像,當其非零時,有著dsize(第三個參數)的尺寸,或者由src.size()計算出來。
- 第三個參數,Size類型的dsize,輸出圖像的大小
- 第四個參數,double類型的fx,沿水平軸的縮放系數,有默認值0
- 第五個參數,double類型的fy,沿垂直軸的縮放系數,有默認值0
- 第五個參數,double類型的fy,沿垂直軸的縮放系數,有默認值0
? ? ?resize( )為OpenCV中專職調整圖像大小的函數。
? ? ?此函數將源圖像精確地轉換為指定尺寸的目標圖像。如果源圖像中設置了ROI(Region Of Interest ,感興趣區域),那么resize( )函數會對源圖像的ROI區域進行調整圖 ? ? ? ?像尺寸的操作,來輸出到目標圖像中。若目標圖像中已經設置ROI區域,不難理解resize( )將會對源圖像進行尺寸調整并填充到目標圖像的ROI中。
? ? ?很多時候,我們并不用考慮第二個參數dst的初始圖像尺寸和類型(即直接定義一個Mat類型,不用對其初始化),因為其尺寸和類型可以由src,dsize,fx和fy這其他的幾個 ? ? ? ?參數來確定。
****************************************************************************************************************************************************************************************
10:pryUp函數剖析
? ? ? ?pyrUp( )函數的作用是向上采樣并模糊一張圖像,說白了就是放大一張圖片
? ? ? ?void?pyrUp(InputArray?src,?OutputArraydst,?const?Size&?dstsize=Size(),?int?borderType=BORDER_DEFAULT?) ?
- 第一個參數,InputArray類型的src,輸入圖像,即源圖像,填Mat類的對象即可。
- 第二個參數,OutputArray類型的dst,輸出圖像,和源圖片有一樣的尺寸和類型。
- 第三個參數,const Size&類型的dstsize,輸出圖像的大小;有默認值Size(),即默認情況下,由Size(src.cols*2,src.rows*2)來進行計算,
- 第四個參數,int類型的borderType,又來了,邊界模式,一般我們不用去管它。
? ? ? ? ? ? 總結一下,OpenCV中的霍夫線變換有如下三種:
? ? ? ? ? ? ? ? <1>標準霍夫變換(StandardHough Transform,SHT),由HoughLines函數調用。
? ? ? ? ? ? ? ? <2>多尺度霍夫變換(Multi-ScaleHough Transform,MSHT),由HoughLines函數調用。
? ? ? ? ? ? ? ? <3>累計概率霍夫變換(ProgressiveProbabilistic Hough Transform,PPHT),由HoughLinesP函數調用。
? ? ? ? ? ?我們可以對圖像中所有的點進行上述操作. 如果兩個不同點進行上述操作后得到的曲線在平面相交, 這就意味著它們通過同一條直線。
?
? ? ? ? ? ?以上的說明表明,一般來說, 一條直線能夠通過在平面??尋找交于一點的曲線數量來檢測。而越多曲線交于一點也就意味著這個交點表示的直線由 ? ? ? ? ? ? ? ? ? ? ? ? ? ?更多的點組成. 一般來說我們可以通過設置直線上點的閾值來定義多少條曲線交于一點我們才認為檢測到了一條直線。
? ? ? ? ? ?這就是霍夫線變換要做的. 它追蹤圖像中每個點對應曲線間的交點. 如果交于一點的曲線的數量超過了閾值, 那么可以認為這個交點所代表的參數對在原圖 ? ? ? ? ? ? ?像中為一條直線。
? ? ? 2:houghLines函數詳解
? ? ? ? ? ?我們可以用其來調用標準霍夫變換SHT和多尺度霍夫變換MSHT的OpenCV內建算法。
? ? ? ? ? ?void?HoughLines(InputArray?image,?OutputArray?lines,?double?rho,?double?theta,?int?threshold,?double?srn=0,?double?stn=0?)?
? ? ? 具體見:http://blog.csdn.net/poem_qianmo/article/details/26977557
***********************************************************************************************************************************
??12:openCV角點檢測之Harris角點檢測
?
? ? ??? ? 當前的圖像處理領域,角點檢測算法可歸納為三類:
? ? ? ??<1>基于灰度圖像的角點檢測
? ? ? ? <2>基于二值圖像的角點檢測
? ? ? ?<3>基于輪廓曲線的角點檢測
? ? ? ?“如果某一點在任意方向的一個微小變動都會引起灰度很大的變化,那么我們就把它稱之為角點“??
?
另外,關于角點的具體描述可以有幾種:
- 一階導數(即灰度的梯度)的局部最大所對應的像素點;
- 兩條及兩條以上邊緣的交點;
- 圖像中梯度值和梯度方向的變化速率都很高的點;
- 角點處的一階導數最大,二階導數為零,指示物體邊緣變化不連續的方向。
cornerHarris函數詳解cornerHarris 函數用于在OpenCV中運行Harris角點檢測算子處理圖像。cornerHarris 函數對于每一個像素(x,y)在鄰域內,計算2x2梯度的協方差矩陣
,接著它計算如下式子:
?,即可以找出輸出圖中的局部最大值,即找出了角點。
函數原型:void?cornerHarris(InputArray?src,OutputArray?dst,?int?blockSize,?int?ksize,?double?k,?intborderType=BORDER_DEFAULT?) ?
- 第一個參數,InputArray類型的src,輸入圖像,即源圖像,填Mat類的對象即可,且需為單通道8位或者浮點型圖像。
- 第二個參數,OutputArray類型的dst,函數調用后的運算結果存在這里,即這個參數用于存放Harris角點檢測的輸出結果,和源圖片有一樣的尺寸和類型。
- 第三個參數,int類型的blockSize,表示鄰域的大小,更多的詳細信息在cornerEigenValsAndVecs()中有講到。
- 第四個參數,int類型的ksize,表示Sobel()算子的孔徑大小。
- 第五個參數,double類型的k,Harris參數。
- 第六個參數,int類型的borderType,圖像像素的邊界模式,注意它有默認值BORDER_DEFAULT。更詳細的解釋,參考borderInterpolate( )函數。
double?threshold(InputArray?src,OutputArray?dst,?double?thresh,?double?maxval,?int?type) ?函數Threshold( ) 對單通道數組應用固定閾值操作。該函數的典型應用是對灰度圖像進行閾值操作得到二值圖像。(另外,compare( )函數也可以達到此目的) 或者是去掉噪聲,例如過濾很小或很大象素值的圖像點。
- 第一個參數,InputArray類型的src,輸入數組,填單通道 , 8或32位浮點類型的Mat即可。
- 第二個參數,OutputArray類型的dst,函數調用后的運算結果存在這里,即這個參數用于存放輸出結果,且和第一個參數中的Mat變量有一樣的尺寸和類型。
- 第三個參數,double類型的thresh,閾值的具體值。
- 第四個參數,double類型的maxval,當第五個參數閾值類型type取 CV_THRESH_BINARY 或CV_THRESH_BINARY_INV 閾值類型時的最大值.
- 第五個參數,int類型的type,閾值類型,。threshold( )函數支持的對圖像取閾值的方法由其確定,
- http://blog.csdn.net/poem_qianmo/article/details/29356187(不是特別明白里面的一些函數)
- ************************************************************************************************************************************************************************
13:重映射與SURF點檢測重映射SURF點檢測OpenCV中關于SURF算法的部分,常常涉及到的是SURF、SurfFeatureDetector、SurfDescriptorExtractor這三個類,這一小節我們就來對他們進行人肉,挖 ? ? ?挖其背景,看看他們究竟是什么來頭。繪制關鍵點的函數:drawKeypoints( )void?drawKeypoints(const?Mat&image,?const?vector<KeyPoint>&?keypoints,?Mat&?outImage,?constScalar&?color=Scalar::all(-1),?? ? ? ? ? ? ? ? ? ?int?flags=DrawMatchesFlags::DEFAULT)
- 第一個參數,const Mat&類型的src,輸入圖像。
- 第二個參數,const vector<KeyPoint>&類型的keypoints,根據源圖像得到的特征點,它是一個輸出參數。
- 第三個參數,Mat&類型的outImage,輸出圖像,其內容取決于第五個參數標識符falgs。
- 第四個參數,const Scalar&類型的color,關鍵點的顏色,有默認值Scalar::all(-1)。
- 第五個參數,int類型的flags,繪制關鍵點的特征標識符,有默認值DrawMatchesFlags::DEFAULT。可以在如下這個結構體中選取值。
SURF檢測大致代碼:
? ? ? ? Mat srcImage1 = imread("D:/TEST_GIT/test2/img/book1.jpg",1);
Mat srcImage2 = imread("D:/TEST_GIT/test2/img/book2.jpg",2);
//【2】定義需要用到的變量和類 ?
int minHessian = 400; //定義SURF中的hessian閾值特征點檢測算子 ?
SurfFeatureDetector detector(minHessian); //定義一個SurfFeatureDetector(SURF) 特征檢測類對象 ?
std::vector<KeyPoint> keypoints_1, keypoints_2; //vector模板類是能夠存放任意類型的動態數組,能夠增加和壓縮數據 ?
//【3】調用detect函數檢測出SURF特征關鍵點,保存在vector容器中 ?
detector.detect(srcImage1, keypoints_1);
detector.detect(srcImage2, keypoints_2);?
//【4】繪制特征關鍵點 ?
Mat img_keypoints_1; Mat img_keypoints_2;
drawKeypoints(srcImage1, keypoints_1, img_keypoints_1, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
drawKeypoints(srcImage2, keypoints_2, img_keypoints_2, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
//【5】顯示效果圖 ?
imshow("特征點檢測效果圖1", img_keypoints_1);
imshow("特征點檢測效果圖2", img_keypoints_2);在OpenCV中,使用SURF進行特征點描述主要是drawMatches方法和BruteForceMatcher類的運用,讓我們一起來認識他們。
- C++:?void?drawMatches(const?Mat&?img1,??
- constvector<KeyPoint>&?keypoints1,??
- ?const?Mat&?img2,??
- ?constvector<KeyPoint>&?keypoints2,??
- ?constvector<DMatch>&?matches1to2,??
- ?Mat&?outImg,??
- ?const?Scalar&matchColor=Scalar::all(-1),??
- ?const?Scalar&singlePointColor=Scalar::all(-1),??
- ?const?vector<char>&matchesMask=vector<char>(),??
- ?intflags=DrawMatchesFlags::DEFAULT?) ?
??drawMatches用于繪制出相匹配的兩個圖像的關鍵點
- 第一個參數,const Mat&類型的img1,第一幅源圖像。
- 第二個參數,const vector<KeyPoint>&類型的keypoints1,根據第一幅源圖像得到的特征點,它是一個輸出參數。
- 第三個參數,const Mat&類型的img2,第二幅源圖像。
- 第四個參數,const vector<KeyPoint>&類型的keypoints2,根據第二幅源圖像得到的特征點,它是一個輸出參數。
- 第五個參數,matches1to2,第一幅圖像到第二幅圖像的匹配點,即表示每一個圖1中的特征點都在圖2中有一一對應的點、
- 第六個參數,Mat&類型的outImg,輸出圖像,其內容取決于第五個參數標識符falgs。
- 第七個參數,const Scalar&類型的matchColor,匹配的輸出顏色,即線和關鍵點的顏色。它有默認值Scalar::all(-1),表示顏色是隨機生成的。
- 第八個參數,const Scalar&類型的singlePointColor,單一特征點的顏色,它也有表示隨機生成顏色的默認值Scalar::all(-1)。
- 第九個參數,matchesMask,確定哪些匹配是會繪制出來的掩膜,如果掩膜為空,表示所有匹配都進行繪制。
- 第十個參數,int類型的flags,特征繪制的標識符,有默認值DrawMatchesFlags::DEFAULT。可以在如下這個DrawMatchesFlags結構體中選取值:
? ? BruteForceMatcher類源碼分析
而我們用BruteForceMatcher類時用到最多的match方法,是它從DescriptorMatcher類那里的“拿來主義”。定義如下:
- //為各種描述符找到一個最佳的匹配(若掩膜為空)??
- CV_WRAP?void?match(?const?Mat&?queryDescriptors,?const?Mat&trainDescriptors,??
- ?????????????CV_OUTvector<DMatch>&?matches,?const?Mat&?mask=Mat()?)?const;
?
程序利用了SURF特征的特征描述辦法,其操作封裝在類SurfFeatureDetector中,利用類內的detect函數可以檢測出SURF特征的關鍵點,保存在vector容器中。第二步利用SurfDescriptorExtractor類進行特征向量的相關計算。將之前的vector變量變成向量矩陣形式保存在Mat中。最后強行匹配兩幅圖像的特征向量,利用了類BruteForceMatcher中的函數match。
程序的核心思想是:
- 使用 DescriptorExtractor 接口來尋找關鍵點對應的特征向量。detector(srcImage,keyPoints)方法
- 使用 SurfDescriptorExtractor 以及它的函數 compute 來完成特定的計算。compute(srcImage,keyPoints, descriptor)方法
- 使用 BruteForceMatcher 來匹配特征向量。match(descriptor1,descriptor2,matches)方法
- 使用函數 drawMatches 來繪制檢測到的匹配點.drawMatches( srcImage1, keyPoint1, srcImage2, keyPoints2, matches, imgMatches)