做網(wǎng)站一天賺多少錢seo崗位有哪些
1.圖像分割概述
(1)What(什么是圖像分割)
將圖像劃分為不同的子區(qū)域,使得同一子區(qū)域具有較高的相似性,不同的子區(qū)域具有明顯的差異性
(2)Why(對(duì)圖像進(jìn)行分割有什么作用)
- 醫(yī)學(xué)領(lǐng)域:將不同組織分割成不同區(qū)域幫助分析病情
- 軍事領(lǐng)域:通過對(duì)圖像的分割,為自動(dòng)目標(biāo)識(shí)別提供參數(shù),為飛行器或武器的精準(zhǔn)導(dǎo)航提供依據(jù)
- 遙感領(lǐng)域:通過遙感圖像分析城市地貌、作物生長情況。此外,云系分析和天氣預(yù)報(bào)都離不開圖像分割
- 交通領(lǐng)域:車輛跟蹤和車牌識(shí)別
- 工業(yè)領(lǐng)域:零部件分類、質(zhì)量評(píng)估等
(3)Which(有哪些圖像分割的方法)
- 基于閾值的分割方法:利用灰度直方圖得到分割的閾值,利用這些閾值將圖像分為幾個(gè)部分,核心思想是認(rèn)為同一部分的像素是同一個(gè)物體。
- 基于邊緣的分割方法:檢測圖像的邊界以實(shí)現(xiàn)對(duì)圖像的分割
- 基于區(qū)域的分割方法:核心思想是將有相似特性的像素集合起來構(gòu)成區(qū)域,將差異性較大的區(qū)域進(jìn)行分裂
- 基于神經(jīng)網(wǎng)絡(luò)的分割方法:這里不多贅言,現(xiàn)在很火…
- 基于聚類的分割方法:依據(jù)像素相似度,使用聚類算法將像素劃分為不同類別
2.基于閾值的分割
(1)固定閾值分割
將圖像分為兩個(gè)部分:黑和白兩個(gè)區(qū)域
/*@author @還下著雨ZG
* @brief 固定閾值圖像分割
* @param[in] imSrc, 待分割的圖像
* @param[out] imSegment, 分割后的圖像
* @param[in] threVal, 輸入的閾值
* @return, 返回正整數(shù)表示圖像分割成功,負(fù)整數(shù)表示失敗
**/
int ImgSegmentByGlbThreVal(const cv::Mat& imSrc, cv::Mat& imSegment, int threVal)
{if(imSrc.empty()) return -1;if(threVal<0 || threVal>255) return -2;// 圖像預(yù)處理cv::Mat imGray;if(imSrc.channels()==1) imGray = imSrc.clone();else if(imSrc.channels() == 3){cv::cvtColor(imSrc, imGray, cv::COLOR_RGB2GRAY);}else{return -3;}cv::GaussianBlur(imGray, imGray, cv::Size(3,3), 0);//全局閾值法cv::threshold(imGray, imSegment, threVal);return 1;
}
閾值分割函數(shù)threshold的介紹:
double cv::threshold(cv::Mat &imSrc, //輸入圖像,應(yīng)該為單通道cv::Mat &imDst, //分割后的圖像,大小和類型和imSrc相同double thresh, //表示閾值double maxval, //最大灰度值,一般設(shè)為255int type //閾值化類型,詳細(xì)介紹如下所示};
參數(shù)type的介紹:type是一個(gè)枚舉類型的數(shù)據(jù)
THRESH_BINARY = 0, // ( x > thresh ) ? 255 : 0
THRESH_BINARY_INV = 1, // ( x > thresh ) ? 0 : 255
THRESH_TRUNC = 2, // ( x > thresh ) ? thresh : x
THRESH_TOZERO = 3, // ( x < thresh ) ? 0 : x
THRESH_TOZERO = 4, // ( x < thresh ) ? x : 0
THRESH_MASK = 7,
THRESH_OTSU = 8, // 自動(dòng)處理,圖像自適應(yīng)二值化,常用區(qū)間【0-255】
(2)自適應(yīng)閾值分割
根據(jù)圖像不同區(qū)域的亮度分布計(jì)算局部閾值,對(duì)于圖像的不同區(qū)域能夠自適應(yīng)計(jì)算不同閾值
void cv::adaptiveThreshold(cv::Mat &imSrc, //輸入的源圖像cv::Mat &imDst, //輸出圖像double maxval, //預(yù)設(shè)滿足條件的最大值int adaptMethod, //指定自適應(yīng)閾值算法類型(ADAPTIVE_MEAN_C或ADAPTIVE_THRESH_GAUSSIAN_C兩種)int threshType, //閾值類型(THRESH_BINARY或THRESH_BINARY_INV)int blockSize, //領(lǐng)域塊的大小,用于計(jì)算區(qū)域閾值(3,5,7 ...)double C, //與算法有關(guān)的參數(shù),是一個(gè)從均值或加權(quán)均值提取的常數(shù),可為負(fù));
使用adaptiveThresh:
/*@author @還下著雨ZG
* @brief 自適應(yīng)閾值圖像分割
* @param[in] imSrc, 待分割的圖像
* @param[out] imSegment, 分割后的圖像
* @return, 返回正整數(shù)表示圖像分割成功,負(fù)整數(shù)表示失敗
**/
int ImgSegmentByAdpThre(const cv::Mat& imSrc, cv::Mat& imSegment)
{if (imSrc.empty()) return -1;cv::Mat imGray;if (imSrc.channels() == 1){cv::copyTo(imSrc, imGray, cv::Mat());}else if (imSrc.channels() == 3){cv::cvtColor(imSrc, imGray, cv::COLOR_RGB2GRAY);}else{return -2;}cv::GaussianBlur(imGray, imGray, cv::Size(3, 3), 0);int blockSize = 3;int constValue = 0;cv::adaptiveThreshold(imGray, imSegment, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, blockSize,constValue);return 1;
}
在實(shí)際使用時(shí),大部分是先通過算子尋找邊緣,然后和區(qū)域生長融合來分割圖像
3.基于區(qū)域的分割
有相似特性的像素集合起來構(gòu)成區(qū)域,將差異性較大的區(qū)域進(jìn)行分裂
(1)分水嶺算法
A.What(分水嶺算法的概念)
將圖像看作是測地學(xué)上的拓?fù)涞孛?#xff0c;每一個(gè)像素的灰度值表示該點(diǎn)的海拔高度,每一個(gè)局部極小值及其影響區(qū)域被稱為盆地,對(duì)應(yīng)得邊界形成分水嶺。
每一個(gè)局部極小值表面,刺穿一個(gè)小孔,然后從小孔浸水,隨著浸入的加深,每一個(gè)局部極小值的影響域慢慢向外擴(kuò)展,兩個(gè)盆地間形成分水嶺。
opencv提供的分水嶺算法原型如下:
void cv::watershed(cv::Mat &imBGR, //三通道8bit的彩色圖像);
B.How(如何使用分水嶺算法對(duì)圖像進(jìn)行分割)
- step01: 圖像預(yù)處理(灰度化、濾波去噪等)
- step02: Canny邊緣檢測
- step03: 查找輪廓(findContours函數(shù)查找輪廓),并把輪廓信息按照不同編號(hào)繪制到watershed的第二次參數(shù)markers上,相當(dāng)于標(biāo)記注水點(diǎn)
- step04: watershed分水嶺算法調(diào)用
- step05: 繪制分割出來的區(qū)域
/*@author @還下著雨ZG
* @param[in] imSrc, 輸入的源圖像
* @param[in] imMarks, 輸出圖像,分割之后的結(jié)果
* @return, 正整數(shù)表示成功,負(fù)整數(shù)表示失敗
*/
int ImgDvdWatershed(const cv::Mat& imSrc, cv::Mat& imMarks)
{//step01 圖像預(yù)處理:灰度+濾波cv::Mat imGray;cv::Mat imGray;if (imSrc.channels() == 1){cv::copyTo(imSrc, imGray, cv::Mat());}else if (imSrc.channels() == 3){cv::cvtColor(imSrc, imGray, cv::COLOR_RGB2GRAY);}else {return -1;}cv::GaussianBlur(imGray, imGray, cv::Size(3, 3), 2); //高斯濾波//Step02 Canny邊緣檢測cv::Mat imEdg(imGray.size(), CV_8UC1);cv::Canny(imGray, imEdg, 40, 110);//Step03 查找輪廓并繪制輪廓std::vector<std::vector<cv::Point>> vCnts;std::vector<cv::Vec4i> hierarchy;cv::findContours(imEdg, vCnts, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);cv::Mat imContours;if (!imMarks.empty()){imMarks.release();}imMarks = cv::Mat(imGray.size(), CV_32S, cv::Scalar::all(0));int iIdx = 0;int compCount = 0;for (; iIdx >= 0; iIdx = hierarchy[iIdx][0], compCount++){cv::drawContours(imMarks, vCnts, iIdx, cv::Scalar::all(compCount + 1), 1, 8, hierarchy);cv::drawContours(imContours, vCnts, iIdx, cv::Scalar(255), 1, 8, hierarchy);}cv::Mat imRGB;if (imSrc.channels() == 1){cv::cvtColor(imSrc, imRGB, cv::COLOR_GRAY2RGB);}else if (imSrc.channels() == 3){imRGB = imSrc.clone();}//Step04 調(diào)用分水嶺算法cv::watershed(imRGB, imMarks);//marks既是輸入?yún)?shù)又是輸出參數(shù)imRGB.release();return 1;
}
說明:該函數(shù)輸出參數(shù)imMarks圖像,同一區(qū)域用相同的數(shù)值標(biāo)識(shí),分水嶺用-1標(biāo)識(shí)
(2)洪水填充法分割圖像
該算法通常對(duì)邊緣圖像進(jìn)行操作,可用于分割出比較完整的外輪廓
int cv::floodFill(cv::Mat &imSrc, //輸入圖像cv::Point seedPt, //填充的起始點(diǎn)cv::Scalar newVal, //填充的像素值cv::Rect *rect=0, //將要重繪區(qū)域的最小邊界矩形區(qū)域cv::Scalar loDiff = cv::Scalar(), //像素值負(fù)差的最大值cv::Scalar upDiff = cv::Scalar(), //像素值正差的最大值int flags = 4 //操作標(biāo)識(shí)符);