基本形態學算法
為什么要做基本形態學算法的研究和實現?是因為形態學是一個非常有力,應用 廣泛的工具,但同時也是研究不是很清楚的工具。往往一個恰到好處的變換,就能夠省下許多的勞動。對此的分類和研究就顯得非常有必要,而相關代碼的積累,也很有價值。
零、基本概念:
膨脹:白->黑; dilate
腐蝕:黑->白; erode
開 : 腐蝕->膨脹 平滑物體輪廓,斷開較窄的地方,清除細突;
閉 :膨脹->腐蝕 彌合較窄的間斷,填補細長的溝壑;
頂帽 :src-(開運算(src))
底帽 :閉運算(src)-src
一、邊界提取
先腐蝕,然后相減。
作為生成算法可能價值不是很大,但是在生成鏤空字符的時候,價值就會比較大。
變成
以及
//-------------------生成驗證碼--------------//
void creatCode()
{
Mat edge;
Mat code = imread( "abcd123.bmp" , 0 );
threshold(code,code, 0 , 255 ,THRESH_OTSU);
threshold(code,code, 0 , 255 ,THRESH_BINARY_INV);
dilate(code,code,Mat( 1 , 5 ,CV_8U));
erode(code,edge,Mat());
edge = code - edge;
imshow( "驗證碼生成" ,code);
}
//-------------------邊界提取----------------//
void getEdge(Mat src)
{
Mat edge ;
erode(src,edge,Mat());
edge = src - edge;
imshow( "邊界提取" ,edge);
}
void creatCode()
{
Mat edge;
Mat code = imread( "abcd123.bmp" , 0 );
threshold(code,code, 0 , 255 ,THRESH_OTSU);
threshold(code,code, 0 , 255 ,THRESH_BINARY_INV);
dilate(code,code,Mat( 1 , 5 ,CV_8U));
erode(code,edge,Mat());
edge = code - edge;
imshow( "驗證碼生成" ,code);
}
//-------------------邊界提取----------------//
void getEdge(Mat src)
{
Mat edge ;
erode(src,edge,Mat());
edge = src - edge;
imshow( "邊界提取" ,edge);
}
二、孔洞填充(注意,floodfill是沒有教程的)
一個孔洞可以被定義為由前景像素相連接的邊界所包圍的一個背景區域。關鍵是標注出區域中的點來。
原文的翻譯實在無法理解。我這里做出自己收集到的實現。
opencv中提供了floodfill的例子,應該說功能強大
對於本例,問題在於如何自動化這個過程?
我實現了一個效果,主要是通過反過來找中間的黑點,然后相加。這里屬於反過來使用floodfill,效果還是不錯的.
NICE!體現形態學的強大能力。如果你用輪廓來找的話,會很麻煩,而且不穩定。但是用形態學,確非常穩定,只有在很特殊的情況下,才可能出現失敗的青年高考。
三、聯通分量提取
從二值圖像中提取聯通分量是許多自動圖形啊分析應用的核心。除了在對應A中每個連通分量中的一個點的已指的每一個位置我們置為1,其他為0
對於8連通,目前采用的算法是find contours。雖然有一些文檔中也提出了一些算法,但是根據我目前的知識結構,還是直接contour的方法最好。
四、【關於細化和骨廓,屆時看不懂】
五、頂帽變換和底帽變換
頂帽變換的一個作用是去除光照不均勻
用於連鑄的效果非常明顯,我相信這樣可以把代碼質量進一步提高
黑帽
去除背景還是要這樣來做
從這點可以看出,它的確是效果要更好一點的。
小結:
形態學變換應該說是很強的,因為它更接近於原始的情況,是不同於輪廓分析的基礎工具。在我之前的過程中確實缺乏這方面的使用,這方面的書還要多讀多用。
P.S.
在OPENCV中,提供了一攬子的解決方法
int main()
{
Mat src = imread("./image/chars_identify.jpg",0);
Mat srcClone = src.clone();
Mat element = getStructuringElement(MORPH_ELLIPSE,Size(7,3));
morphologyEx(src,srcClone,CV_MOP_TOPHAT,element);
imshow("src",src);
imshow("srcClone",srcClone);
waitKey();
}
分為兩個部分,首先生成一個element,然后根據參數的不同,進行形態學變換
/* Morphological operations */
enum
{
CV_MOP_ERODE =0,
CV_MOP_DILATE =1,
CV_MOP_OPEN =2,
CV_MOP_CLOSE =3,
CV_MOP_GRADIENT =4,
CV_MOP_TOPHAT =5,
CV_MOP_BLACKHAT =6
};
