加載圖像 cv::imread;
修改圖像? cv::cvtColor;
保存圖片? cv::imwrite实辑;
kernel = getStructuringElement(MORPH_RECT, Size(5, 5));
//getStructuringElement函數(shù)會(huì)返回指定形狀和尺寸的結(jié)構(gòu)元素(int shape, Size esize, Point anchor = Point(-1, -1))
//這個(gè)函數(shù)的第一個(gè)參數(shù)表示內(nèi)核的形狀,有三種形狀可以選擇。
//矩形:MORPH_RECT;
//交叉形:MORPH_CORSS;
//橢圓形:MORPH_ELLIPSE;
//第二和第三個(gè)參數(shù)分別是內(nèi)核的尺寸以及錨點(diǎn)的位置。
//一般在調(diào)用erode以及dilate函數(shù)之前粉铐,先定義一個(gè)Mat類型的變量來(lái)獲得getStructuringElement函數(shù)的返回值或粮。
//對(duì)于錨點(diǎn)的位置,有默認(rèn)值Point(-1,-1)诊沪,表示錨點(diǎn)位于中心點(diǎn)。
//element形狀唯一依賴錨點(diǎn)位置曾撤,其他情況下端姚,錨點(diǎn)只是影響了形態(tài)學(xué)運(yùn)算結(jié)果的偏移
inRange(frame, Scalar(0, 80, 80), Scalar(50, 255, 255), dst);
//開(kāi)操作
//可實(shí)現(xiàn)二值化功能(這點(diǎn)類似threshold()函數(shù)),更關(guān)鍵的是可以同時(shí)針對(duì)多通道進(jìn)行操作挤悉,使用起來(lái)非常方便渐裸!
//參數(shù)1:輸入要處理的圖像巫湘,可以為單通道或多通道。
//參數(shù)2:包含下邊界的數(shù)組或標(biāo)量昏鹃。
//參數(shù)3:包含上邊界數(shù)組或標(biāo)量尚氛。
//參數(shù)4:輸出圖像,與輸入圖像src 尺寸相同且為CV_8U 類型洞渤。
高級(jí)形態(tài)學(xué)變換:
開(kāi)運(yùn)算:
先腐蝕阅嘶,再膨脹,可清除一些小東西(亮的)载迄,放大局部低亮度的區(qū)域
閉運(yùn)算:
先膨脹讯柔,再腐蝕,可清除小黑點(diǎn)
形態(tài)學(xué)梯度:
膨脹圖與腐蝕圖之差护昧,提取物體邊緣
頂帽:
原圖像-開(kāi)運(yùn)算圖魂迄,突出原圖像中比周圍亮的區(qū)域
黑帽:
閉運(yùn)算圖-原圖像,突出原圖像中比周圍暗的區(qū)域
腐蝕用于分割(isolate)獨(dú)立的圖像元素惋耙,
膨脹用于連接(join)相鄰的元素
腐蝕捣炬、膨脹可用于去噪(低尺寸結(jié)構(gòu)元素的腐蝕操作很容易去掉分散的椒鹽噪聲點(diǎn)),
圖像輪廓提取绽榛、圖像分割湿酸、尋找圖像中的明顯的極大值區(qū)域或極小值區(qū)域等
腐蝕和膨脹是最基本的形態(tài)學(xué)算子
結(jié)構(gòu)元素
就相當(dāng)于我們?cè)跒V波中所涉及到的模板,也就是說(shuō)它是一個(gè)給定像素的矩陣灭美,這個(gè)矩陣可以是任意形狀的稿械,
一般情況下都是正方形,圓形或者菱形的但是在結(jié)構(gòu)元素中有一個(gè)中心點(diǎn)(也叫做anchor point)冲粤。
和模板中心一樣,處理后的結(jié)果賦值給和這個(gè)中心點(diǎn)對(duì)齊的像素點(diǎn)页眯。處理的過(guò)程也是基本相同梯捕。
結(jié)構(gòu)元素和卷積模板的區(qū)別在于,膨脹是以集合運(yùn)算為基礎(chǔ)的窝撵,卷積是以算數(shù)運(yùn)算為基礎(chǔ)的傀顾。
(OpenCV里面的腐蝕膨脹都是針對(duì)白色目標(biāo)區(qū)域的)
膨脹:用結(jié)構(gòu)元素的中心點(diǎn)對(duì)準(zhǔn)當(dāng)前正在遍歷的這個(gè)像素,
然后取當(dāng)前結(jié)構(gòu)元素所覆蓋下的原圖對(duì)應(yīng)區(qū)域內(nèi)的所有像素的最大值碌奉,用這個(gè)最大值替換當(dāng)前像素值短曾,給圖像中的對(duì)象邊界添加像素,使二值圖像擴(kuò)大一圈
1. 用結(jié)構(gòu)元素赐劣,掃描圖像的每一個(gè)像素
2. 用結(jié)構(gòu)元素與其覆蓋的二值圖像做“與”操作
3. 如果都為0嫉拐,結(jié)果圖像的該像素為0。否則為1
也就是在結(jié)構(gòu)元素覆蓋范圍下魁兼,只要有一個(gè)像素符和結(jié)構(gòu)元素像素相同婉徘,那么中心點(diǎn)對(duì)應(yīng)點(diǎn)就為1,否則為0
腐蝕:用結(jié)構(gòu)元素的中心點(diǎn)對(duì)準(zhǔn)當(dāng)前正在遍歷的這個(gè)像素,
然后取當(dāng)前結(jié)構(gòu)元素所覆蓋下的原圖對(duì)應(yīng)區(qū)域內(nèi)的所有像素的最小值盖呼,用這個(gè)最小值替換當(dāng)前像素值儒鹿,刪除對(duì)象邊界的某些像素,使二值圖像減小一圈
1. 用結(jié)構(gòu)元素几晤,掃描圖像的每一個(gè)像素
2. 用結(jié)構(gòu)元素與其覆蓋的二值圖像做“與”操作
3. 如果都為1约炎,結(jié)果圖像的該像素為1。否則為0
也就是查找被處理圖像中能不能找到和結(jié)構(gòu)元素相同的矩陣蟹瘾。如果存在那么中心點(diǎn)所對(duì)應(yīng)的點(diǎn)就為1圾浅,否則為0
腐蝕:刪除對(duì)象邊界的某些像素
膨脹:給圖像中的對(duì)象邊界添加像素
//! 侵蝕圖像(應(yīng)用局部最小算子)
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
結(jié)果輸出圖像
kernel
結(jié)構(gòu)元素
anchor
結(jié)構(gòu)元素的原點(diǎn)
iterations
迭代次數(shù)
//! 膨脹圖像(應(yīng)用局部最大算子)
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
結(jié)果輸出圖像
kernel
結(jié)構(gòu)元素
anchor
結(jié)構(gòu)元素的原點(diǎn)
iterations
迭代次數(shù)
常用的結(jié)構(gòu)元素的形狀:
矩形(包括線形)、橢圓(包括圓形)及十字形热芹。
MORPH_RECT
MORPH_ELLIPSE
MORPH_CROSS
//! 返回指定形狀和大小的結(jié)構(gòu)化元素
CV_EXPORTS_W Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1));
取結(jié)構(gòu)元素(內(nèi)核矩陣)贱傀,包括結(jié)構(gòu)元素的大小及形狀:
shape
內(nèi)核的形狀: MORPH_RECT、MORPH_ELLIPSE伊脓、MORPH_CROSS
ksize
內(nèi)核的尺寸
anchor
錨點(diǎn)的位置, Point(-1,-1)錨點(diǎn)位于中心
//! 對(duì)圖像應(yīng)用高級(jí)形態(tài)操作
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函數(shù)利用基本的膨脹和腐蝕技術(shù)府寒,來(lái)執(zhí)行更加高級(jí)形態(tài)學(xué)變換
MORPH_OPEN – 開(kāi)運(yùn)算(Opening operation)
MORPH_CLOSE – 閉運(yùn)算(Closing operation)
MORPH_GRADIENT - 形態(tài)學(xué)梯度(Morphological gradient)
MORPH_TOPHAT - 頂帽(Top hat)
MORPH_BLACKHAT - 黑帽(Black hat)
kernel
形態(tài)學(xué)運(yùn)算的內(nèi)核。為NULL报腔,使用參考點(diǎn)位于中心3x3的核株搔。一般使用函數(shù)getStructuringElement配合這個(gè)參數(shù)的使用,
kernel參數(shù)填保存getStructuringElement返回值的Mat類型變量纯蛾。
anchor
錨的位置纤房,其有默認(rèn)值(-1,-1)翻诉,表示錨位于中心炮姨。
iterations
迭代使用函數(shù)的次數(shù),默認(rèn)值為1碰煌。
borderType
用于推斷圖像外部像素的某種邊界模式舒岸。注意它有默認(rèn)值BORDER_CONSTANT。
borderValue
當(dāng)邊界為常數(shù)時(shí)的邊界值芦圾,有默認(rèn)值morphologyDefaultBorderValue()蛾派,
opencv中提供findContours()函數(shù)來(lái)尋找圖像中物體的輪廓,并結(jié)合drawContours()函數(shù)將找到的輪廓繪制出个少。
首先看一下findContours(),opencv中提供了兩種定義形式
//找輪廓
findContours()
void cv::findContours? (? InputOutputArray? ? image,
? ? ? ? ? ? ? ? ? ? ? ? ? ? OutputArrayOfArrays? ? contours,
? ? ? ? ? ? OutputArray? ? hierarchy,
? ? ? ? ? ? ? ? ? ? ? ? ? ? int? ? mode,
? ? ? ? ? ? ? ? ? ? ? ? ? ? int? ? method,
? ? ? ? ? Point? offset = Point()
? ? ? ? ? ? ? ? ? ? ? ? )?
image:輸入圖像
contours:檢測(cè)到的輪廓洪乍,每個(gè)輪廓都是以點(diǎn)向量的形式進(jìn)行存儲(chǔ)即使用point類型的vector表示
hierarchy:可選的輸出向量(std::vector),包含了圖像的拓?fù)湫畔⒁菇梗鳛檩喞獢?shù)量的表示hierarchy包含了很多元素壳澳,
每個(gè)輪廓contours[i]對(duì)應(yīng)hierarchy中hierarchy[i][0]~hierarchy[i][3],分別表示后一個(gè)輪廓,前一個(gè)輪廓糊探,父輪廓钾埂,內(nèi)嵌輪廓的索引河闰,如果沒(méi)有對(duì)應(yīng)項(xiàng),則相應(yīng)的hierarchy[i]設(shè)置為負(fù)數(shù)褥紫。
mode:輪廓檢索模式
{
RETR_EXTERNAL:表示只檢測(cè)最外層輪廓姜性,對(duì)所有輪廓設(shè)置hierarchy[i][2]=hierarchy[i][3]=-1
RETR_LIST:提取所有輪廓,并放置在list中髓考,檢測(cè)的輪廓不建立等級(jí)關(guān)系
RETR_CCOMP:提取所有輪廓部念,并將輪廓組織成雙層結(jié)構(gòu)(two-level hierarchy),頂層為連通域的外圍邊界,次層位內(nèi)層邊界
RETR_TREE:提取所有輪廓并重新建立網(wǎng)狀輪廓結(jié)構(gòu)
RETR_FLOODFILL:官網(wǎng)沒(méi)有介紹氨菇,應(yīng)該是洪水填充法
}
method:輪廓近似方法
{
CHAIN_APPROX_NONE:獲取每個(gè)輪廓的每個(gè)像素儡炼,相鄰的兩個(gè)點(diǎn)的像素位置差不超過(guò)1
CHAIN_APPROX_SIMPLE:壓縮水平方向,垂直方向查蓉,對(duì)角線方向的元素乌询,值保留該方向的重點(diǎn)坐標(biāo),如果一個(gè)矩形輪廓只需4個(gè)點(diǎn)來(lái)保存輪廓信息
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檢測(cè)到的輪廓數(shù)據(jù)妹田,每個(gè)輪廓以點(diǎn)向量的形式存儲(chǔ),point類型的vector
contourIdx:繪制輪廓的只是變量鹃共,如果為負(fù)值則繪制所有輸入輪廓
color:輪廓顏色
thickness:繪制輪廓所用線條粗細(xì)度鬼佣,如果值為負(fù)值,則在輪廓內(nèi)部繪制
lineTpye:線條類型霜浴,有默認(rèn)值LINE_8晶衷,有如下可選類型
{
hierarchy:可選層次結(jié)構(gòu)信息
maxLevel:用于繪制輪廓的最大等級(jí)
offset:可選輪廓便宜參數(shù),用制定偏移量offset=(dx, dy)給出繪制輪廓的偏移量
}