加載圖像 cv::imread;
修改圖像? cv::cvtColor;
保存圖片? cv::imwrite;
kernel = getStructuringElement(MORPH_RECT, Size(5, 5));
//getStructuringElement函數會返回指定形狀和尺寸的結構元素(int shape, Size esize, Point anchor = Point(-1, -1))
//這個函數的第一個參數表示內核的形狀,有三種形狀可以選擇。
//矩形:MORPH_RECT;
//交叉形:MORPH_CORSS;
//橢圓形:MORPH_ELLIPSE;
//第二和第三個參數分別是內核的尺寸以及錨點的位置。
//一般在調用erode以及dilate函數之前,先定義一個Mat類型的變量來獲得getStructuringElement函數的返回值。
//對于錨點的位置,有默認值Point(-1,-1),表示錨點位于中心點。
//element形狀唯一依賴錨點位置,其他情況下,錨點只是影響了形態學運算結果的偏移
inRange(frame, Scalar(0, 80, 80), Scalar(50, 255, 255), dst);
//開操作
//可實現二值化功能(這點類似threshold()函數),更關鍵的是可以同時針對多通道進行操作,使用起來非常方便!
//參數1:輸入要處理的圖像,可以為單通道或多通道。
//參數2:包含下邊界的數組或標量。
//參數3:包含上邊界數組或標量。
//參數4:輸出圖像,與輸入圖像src 尺寸相同且為CV_8U 類型。
高級形態學變換:
開運算:
先腐蝕,再膨脹,可清除一些小東西(亮的),放大局部低亮度的區域
閉運算:
先膨脹,再腐蝕,可清除小黑點
形態學梯度:
膨脹圖與腐蝕圖之差,提取物體邊緣
頂帽:
原圖像-開運算圖,突出原圖像中比周圍亮的區域
黑帽:
閉運算圖-原圖像,突出原圖像中比周圍暗的區域
腐蝕用于分割(isolate)獨立的圖像元素,
膨脹用于連接(join)相鄰的元素
腐蝕、膨脹可用于去噪(低尺寸結構元素的腐蝕操作很容易去掉分散的椒鹽噪聲點),
圖像輪廓提取、圖像分割、尋找圖像中的明顯的極大值區域或極小值區域等
腐蝕和膨脹是最基本的形態學算子
結構元素
就相當于我們在濾波中所涉及到的模板,也就是說它是一個給定像素的矩陣,這個矩陣可以是任意形狀的,
一般情況下都是正方形,圓形或者菱形的但是在結構元素中有一個中心點(也叫做anchor point)。
和模板中心一樣,處理后的結果賦值給和這個中心點對齊的像素點。處理的過程也是基本相同。
結構元素和卷積模板的區別在于,膨脹是以集合運算為基礎的,卷積是以算數運算為基礎的。
(OpenCV里面的腐蝕膨脹都是針對白色目標區域的)
膨脹:用結構元素的中心點對準當前正在遍歷的這個像素,
然后取當前結構元素所覆蓋下的原圖對應區域內的所有像素的最大值,用這個最大值替換當前像素值,給圖像中的對象邊界添加像素,使二值圖像擴大一圈
1. 用結構元素,掃描圖像的每一個像素
2. 用結構元素與其覆蓋的二值圖像做“與”操作
3. 如果都為0,結果圖像的該像素為0。否則為1
也就是在結構元素覆蓋范圍下,只要有一個像素符和結構元素像素相同,那么中心點對應點就為1,否則為0
腐蝕:用結構元素的中心點對準當前正在遍歷的這個像素,
然后取當前結構元素所覆蓋下的原圖對應區域內的所有像素的最小值,用這個最小值替換當前像素值,刪除對象邊界的某些像素,使二值圖像減小一圈
1. 用結構元素,掃描圖像的每一個像素
2. 用結構元素與其覆蓋的二值圖像做“與”操作
3. 如果都為1,結果圖像的該像素為1。否則為0
也就是查找被處理圖像中能不能找到和結構元素相同的矩陣。如果存在那么中心點所對應的點就為1,否則為0
腐蝕:刪除對象邊界的某些像素
膨脹:給圖像中的對象邊界添加像素
//! 侵蝕圖像(應用局部最小算子)
CV_EXPORTS_W void erode( InputArray src, OutputArray dst, InputArray kernel,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Point anchor=Point(-1,-1), int iterations=1,
? ? ? ? ? ? int borderType=BORDER_CONSTANT,
? ? ? ? ? ? const Scalar& borderValue=morphologyDefaultBorderValue() );
src
原圖像
dst
結果輸出圖像
kernel
結構元素
anchor
結構元素的原點
iterations
迭代次數
//! 膨脹圖像(應用局部最大算子)
CV_EXPORTS_W void dilate( InputArray src, OutputArray dst, InputArray kernel,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Point anchor=Point(-1,-1), int iterations=1,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int borderType=BORDER_CONSTANT,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const Scalar& borderValue=morphologyDefaultBorderValue() );
src
原圖像
dst
結果輸出圖像
kernel
結構元素
anchor
結構元素的原點
iterations
迭代次數
常用的結構元素的形狀:
矩形(包括線形)、橢圓(包括圓形)及十字形。
MORPH_RECT
MORPH_ELLIPSE
MORPH_CROSS
//! 返回指定形狀和大小的結構化元素
CV_EXPORTS_W Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1));
取結構元素(內核矩陣),包括結構元素的大小及形狀:
shape
內核的形狀: MORPH_RECT、MORPH_ELLIPSE、MORPH_CROSS
ksize
內核的尺寸
anchor
錨點的位置, Point(-1,-1)錨點位于中心
//! 對圖像應用高級形態操作
CV_EXPORTS_W void morphologyEx( InputArray src, OutputArray dst,
? ? ? ? int op, InputArray kernel,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Point anchor=Point(-1,-1), int iterations=1,
? ? ? ? int borderType=BORDER_CONSTANT,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const Scalar& borderValue=morphologyDefaultBorderValue() );
morphologyEx函數利用基本的膨脹和腐蝕技術,來執行更加高級形態學變換
MORPH_OPEN – 開運算(Opening operation)
MORPH_CLOSE – 閉運算(Closing operation)
MORPH_GRADIENT - 形態學梯度(Morphological gradient)
MORPH_TOPHAT - 頂帽(Top hat)
MORPH_BLACKHAT - 黑帽(Black hat)
kernel
形態學運算的內核。為NULL,使用參考點位于中心3x3的核。一般使用函數getStructuringElement配合這個參數的使用,
kernel參數填保存getStructuringElement返回值的Mat類型變量。
anchor
錨的位置,其有默認值(-1,-1),表示錨位于中心。
iterations
迭代使用函數的次數,默認值為1。
borderType
用于推斷圖像外部像素的某種邊界模式。注意它有默認值BORDER_CONSTANT。
borderValue
當邊界為常數時的邊界值,有默認值morphologyDefaultBorderValue(),
opencv中提供findContours()函數來尋找圖像中物體的輪廓,并結合drawContours()函數將找到的輪廓繪制出。
首先看一下findContours(),opencv中提供了兩種定義形式
//找輪廓
findContours()
void cv::findContours? (? InputOutputArray? ? image,
? ? ? ? ? ? ? ? ? ? ? ? ? ? OutputArrayOfArrays? ? contours,
? ? ? ? ? ? OutputArray? ? hierarchy,
? ? ? ? ? ? ? ? ? ? ? ? ? ? int? ? mode,
? ? ? ? ? ? ? ? ? ? ? ? ? ? int? ? method,
? ? ? ? ? Point? offset = Point()
? ? ? ? ? ? ? ? ? ? ? ? )?
image:輸入圖像
contours:檢測到的輪廓,每個輪廓都是以點向量的形式進行存儲即使用point類型的vector表示
hierarchy:可選的輸出向量(std::vector),包含了圖像的拓撲信息,作為輪廓數量的表示hierarchy包含了很多元素,
每個輪廓contours[i]對應hierarchy中hierarchy[i][0]~hierarchy[i][3],分別表示后一個輪廓,前一個輪廓,父輪廓,內嵌輪廓的索引,如果沒有對應項,則相應的hierarchy[i]設置為負數。
mode:輪廓檢索模式
{
RETR_EXTERNAL:表示只檢測最外層輪廓,對所有輪廓設置hierarchy[i][2]=hierarchy[i][3]=-1
RETR_LIST:提取所有輪廓,并放置在list中,檢測的輪廓不建立等級關系
RETR_CCOMP:提取所有輪廓,并將輪廓組織成雙層結構(two-level hierarchy),頂層為連通域的外圍邊界,次層位內層邊界
RETR_TREE:提取所有輪廓并重新建立網狀輪廓結構
RETR_FLOODFILL:官網沒有介紹,應該是洪水填充法
}
method:輪廓近似方法
{
CHAIN_APPROX_NONE:獲取每個輪廓的每個像素,相鄰的兩個點的像素位置差不超過1
CHAIN_APPROX_SIMPLE:壓縮水平方向,垂直方向,對角線方向的元素,值保留該方向的重點坐標,如果一個矩形輪廓只需4個點來保存輪廓信息
CHAIN_APPROX_TC89_L1和CHAIN_APPROX_TC89_KCOS使用Teh-Chinl鏈逼近算法中的一種
}
//畫輪廓
drawContours()
void cv::drawContours? (? InputOutputArray? ? image,
? ? ? ? ? ? ? ? ? ? ? ? ? ? InputArrayOfArrays? contours,
? ? ? ? ? ? int? ? contourIdx,
? ? ? ? ? ? ? ? ? ? ? ? ? ? const Scalar &? color,
? ? ? ? ? ? ? ? ? ? ? ? ? ? int? ? thickness = 1,
? ? ? ? ? ? ? ? ? ? ? ? ? ? int? ? lineType = LINE_8,
? ? ? ? ? ? ? ? ? ? ? ? ? ? InputArray? hierarchy = noArray(),
? ? ? ? ? ? int? ? maxLevel = INT_MAX,
? ? ? ? ? ? ? ? ? ? ? ? ? ? Point? offset = Point()
)
image:輸入輸出圖像,Mat類型即可
contours:使用findContours檢測到的輪廓數據,每個輪廓以點向量的形式存儲,point類型的vector
contourIdx:繪制輪廓的只是變量,如果為負值則繪制所有輸入輪廓
color:輪廓顏色
thickness:繪制輪廓所用線條粗細度,如果值為負值,則在輪廓內部繪制
lineTpye:線條類型,有默認值LINE_8,有如下可選類型
{
hierarchy:可選層次結構信息
maxLevel:用于繪制輪廓的最大等級
offset:可選輪廓便宜參數,用制定偏移量offset=(dx, dy)給出繪制輪廓的偏移量
}