Zi 字媒體
2017-07-25T20:27:27+00:00
OPENCV 圖像分割 前置動作 流程(SOP) 整理
GITHUB: https://github.com/jash-git/CPP_opencv249_ex [ opencv_ex33 ]
01.彩色圖像邊緣銳化(加強)
◎把彩色圖的背景由白色變黑
◎用filter2D函數對彩色圖片做二階拉式濾波 [PS要把格式從CV_8UC3 設定(轉換)成 CV_32F]
◎將原彩色圖像和二階拉式濾波相減 [PS要把原圖格式從CV_8UC3 設定(轉換)成 CV_32F]
◎上述相減結果即是答案 [PS要把圖像格式從CV_32F 設定(轉換)成 CV_8UC3]
02.彩色圖像求二值化
//---
//彩色轉灰階+二值化
Mat binaryImg;
cvtColor(src, resultImg, CV_BGR2GRAY);
threshold(resultImg, binaryImg, 40, 255, THRESH_BINARY | THRESH_OTSU);//40閥值,要額外做實驗取得,所以環境很重要,實務上要用定光源
imshow("binary image", binaryImg);
//---彩色轉灰階+二值化
03.計算輪廓距離+數據正規化+第二次的二值化 [只留下距離邊緣最遠的點]
/*
Distance Transform 經常應用在二值影像,其運算結果則為一灰階影像,
其強度並非表示亮度值,而是表示物件內部每一點與物件邊緣的距離。
如果以 1 表示物件像素,0 是背景像素,則 distance transform 定義為
對於每一個物件區域的像素,計算其與最近的背景像素的距離,並以此距離值取代原像素值。
輪廓距離
void distanceTransform(InputArray src, OutputArray dst, int distanceType, int maskSize)
src:輸入圖,8位元單通道(通常為二值化圖)。
dst:輸出圖,32位元單通道浮點數圖,和src的尺寸相同。
distanceType:距離型態,可以選擇CV_DIST_L1、CV_DIST_L2或CV_DIST_C。
maskSize:遮罩尺寸,可以選3、5或CV_DIST_MASK_PRECISE,當 distanceType為CV_DIST_L1或CV_DIST_C,這個參數限制為3(因為3和5的結果相同)。
*/
distanceTransform(binaryImg, distImg, CV_DIST_L2, 3);
normalize(distImg, distImg, 0, 1, NORM_MINMAX);
imshow("distance result", distImg);
threshold(distImg, distImg, .4, 1, THRESH_BINARY);//只留下距離邊緣最遠的點
imshow("distance binary image", distImg);
04.使用侵蝕演算法去除過小雜點
Mat k1 = Mat::ones(13, 13, CV_8UC1);
/*
侵蝕
erode(const Mat &src, Mat &dst, Mat kernel, Point anchor=Point(-1,-1), int iterations=1)
src:輸入圖,可以多通道,深度可為CV_8U、CV_16U、CV_16S、CV_32F或CV_64F。
dst:輸出圖,和輸入圖尺寸、型態相同。
kernel:結構元素,如果kernel=Mat()則為預設的3×3矩形,越大侵蝕效果越明顯。
anchor:原點位置,預設為結構元素的中央。
iterations:執行次數,預設為1次,執行越多次侵蝕效果越明顯。
*/
erode(distImg, distImg, k1, Point(-1, -1));
imshow("distance binary_erode image", distImg);
05.透過找邊緣函數標記所有[距離邊緣最遠的點]的座標位置
Mat dist_8u;
distImg.convertTo(dist_8u, CV_8U);
vector< vector > contours;
findContours(dist_8u, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
06.最後利用分水嶺API分割出每一塊圖片位置
/*
OpenCV分水嶺
void watershed(InputArray image, InputOutputArray markers)
image:輸入圖,8位元3通道圖。
markers:輸入輸出標記圖,32位元單通道圖,尺寸必須和image相同。
*/
watershed(src, markers);
Mat mark = Mat::zeros(markers.size(), CV_8UC1);
寫了
5860316篇文章,獲得
23313次喜歡