0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

分水嶺算法(理論+opencv實(shí)現(xiàn))

lviY_AI_shequ ? 來(lái)源:未知 ? 作者:李建兵 ? 2018-03-17 11:06 ? 次閱讀

???把圖像用一維坐標(biāo)表示,二維和三維不好畫(huà),必須用matlab了,我不會(huì)用,意思可以表述到位

第一步:找到圖像的局部最低點(diǎn),這個(gè)方法很多了,可以用一個(gè)內(nèi)核去找,也可以一個(gè)一個(gè)比較,實(shí)現(xiàn)起來(lái)不難。

第二步:從最低點(diǎn)開(kāi)始注水,水開(kāi)始網(wǎng)上滿(圖像的說(shuō)法就是梯度法),其中那些最低點(diǎn)已經(jīng)被標(biāo)記,不會(huì)被淹沒(méi),那些中間點(diǎn)是被淹沒(méi)的。

第三步:找到局部最高點(diǎn),就是圖中3位置對(duì)應(yīng)的兩個(gè)點(diǎn)。

第四步:這樣基于局部最小值,和找到的局部最大值,就可以分割圖像了。

分類圖

模擬結(jié)果圖

是不是感覺(jué)上面的方法很好,也很簡(jiǎn)單?接著看下面的圖:

利用上面的步驟,第一步找到了三個(gè)點(diǎn),然后第二步開(kāi)始漫水,這三個(gè)點(diǎn)都被記錄下來(lái)了,又找到兩個(gè)局部最大值。

這是我們想要的嗎?

回答是否定的!其中中間那個(gè)最小值我們不需要,因?yàn)橹皇且粋€(gè)很少并且很小的噪點(diǎn)而已,我們不需要圖像分割的那么細(xì)致。

缺陷顯露出來(lái)了吧?沒(méi)關(guān)系,下面我們的opencv把這個(gè)問(wèn)題解決了。

模擬分類圖

模擬結(jié)果圖

opencv改進(jìn)的分水嶺算法

針對(duì)上面出現(xiàn)的問(wèn)題,我們想到的是能不能給這種小細(xì)節(jié)一個(gè)標(biāo)記,讓它不屬于我們找的最小的點(diǎn)呢?

opencv對(duì)其改進(jìn)就是使用了人工標(biāo)記的方法,我們標(biāo)記一些點(diǎn),基于這些點(diǎn)去引導(dǎo)分水嶺算法的進(jìn)行,效果很好!

比如我們對(duì)上面的圖像標(biāo)記了兩個(gè)三角形,第一步我們找到三個(gè)局部最小點(diǎn),第二步淹沒(méi)的時(shí)候三個(gè)點(diǎn)都被淹沒(méi)了,然而中間那個(gè)沒(méi)被標(biāo)記,那就淹死了(沒(méi)有救生圈),其余兩個(gè)點(diǎn)保留,這樣就可以達(dá)到我們的想要的結(jié)果了。

注釋:這里的標(biāo)記是用不同的標(biāo)號(hào)進(jìn)行的,我為了方便使用了同樣的三角形了。因?yàn)闃?biāo)記用來(lái)分類,所以不同的標(biāo)記打上不同的標(biāo)號(hào)!這在下面opencv程序中體現(xiàn)了。。。

模擬分類圖

模擬結(jié)果圖

注釋:具體的實(shí)現(xiàn)沒(méi)有完成,感覺(jué)原理懂了會(huì)使用了這樣就可以了,當(dāng)你需要深入的時(shí)候再去研究實(shí)現(xiàn)的算法,當(dāng)你淺淺的使用懂了原理應(yīng)該會(huì)改一點(diǎn),面試過(guò)了完全可以??!哈哈哈~~

opencv實(shí)現(xiàn):

#include

#include

using namespace cv;

using namespace std;

void waterSegment(InputArray& _src, OutputArray& _dst, int& noOfSegment);

int main(int argc, char** argv) {

Mat inputImage = imread("coins.jpg");

assert(!inputImage.data);

Mat graImage, outputImage;

int offSegment;

waterSegment(inputImage, outputImage, offSegment);

waitKey(0);

return 0;

}

void waterSegment(InputArray& _src,OutputArray& _dst,int& noOfSegment)

{

Mat src = _src.getMat();//dst = _dst.getMat();

Mat grayImage;

cvtColor(src, grayImage,CV_BGR2GRAY);

threshold(grayImage, grayImage, 0, 255, THRESH_BINARY | THRESH_OTSU);

Mat kernel = getStructuringElement(MORPH_RECT, Size(9, 9), Point(-1, -1));

morphologyEx(grayImage, grayImage, MORPH_CLOSE, kernel);

distanceTransform(grayImage, grayImage, DIST_L2, DIST_MASK_3, 5);

normalize(grayImage, grayImage,0,1, NORM_MINMAX);

grayImage.convertTo(grayImage, CV_8UC1);

threshold(grayImage, grayImage,0,255, THRESH_BINARY | THRESH_OTSU);

morphologyEx(grayImage, grayImage, MORPH_CLOSE, kernel);

vector> contours;

vector hierarchy;

Mat showImage = Mat::zeros(grayImage.size(), CV_32SC1);

findContours(grayImage, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(-1, -1));

for (size_t i = 0; i < contours.size(); i++)

{

//這里static_cast(i+1)是為了分水嶺的標(biāo)記不同,區(qū)域1、2、3。。。。這樣才能分割

drawContours(showImage, contours, static_cast(i), Scalar::all(static_cast(i+1)), 2);

}

Mat k = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));

morphologyEx(src, src, MORPH_ERODE, k);

watershed(src, showImage);

//隨機(jī)分配顏色

vector colors;

for (size_t i = 0; i < contours.size(); i++) {

int r = theRNG().uniform(0, 255);

int g = theRNG().uniform(0, 255);

int b = theRNG().uniform(0, 255);

colors.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));

}

// 顯示

Mat dst = Mat::zeros(showImage.size(), CV_8UC3);

int index = 0;

for (int row = 0; row < showImage.rows; row++) {

for (int col = 0; col < showImage.cols; col++) {

index = showImage.at(row, col);

if (index > 0 && index <= contours.size()) {

dst.at(row, col) = colors[index - 1];

}

else if (index == -1)

{

dst.at(row, col) = Vec3b(255, 255, 255);

}

else {

dst.at(row, col) = Vec3b(0, 0, 0);

}

}

}

}

分水嶺合并代碼:

void segMerge(Mat& image, Mat& segments, int& numSeg)

{

vector samples;

int newNumSeg = numSeg;

//初始化變量長(zhǎng)度的Vector

for (size_t i = 0; i < newNumSeg; i++)

{

Mat sample;

samples.push_back(sample);

}

for (size_t i = 0; i < segments.rows; i++)

{

for (size_t j = 0; j < segments.cols; j++)

{

int index = segments.at(i, j);

if (index >= 0 && index <= newNumSeg)//把同一個(gè)區(qū)域的點(diǎn)合并到一個(gè)Mat中

{

if (!samples[index].data)//數(shù)據(jù)為空不能合并,否則報(bào)錯(cuò)

{

samples[index] = image(Rect(j, i, 1, 1));

}

else//按行合并

{

vconcat(samples[index], image(Rect(j, i, 2, 1)), samples[index]);

}

}

//if (index >= 0 && index <= newNumSeg)

// samples[index].push_back(image(Rect(j, i, 1, 1)));

}

}

vector hist_bases;

Mat hsv_base;

int h_bins = 35;

int s_bins = 30;

int histSize[2] = { h_bins , s_bins };

float h_range[2] = { 0,256 };

float s_range[2] = { 0,180 };

const float* range[2] = { h_range,s_range };

int channels[2] = { 0,1 };

Mat hist_base;

for (size_t i = 1; i < numSeg; i++)

{

if (samples[i].dims > 0)

{

cvtColor(samples[i], hsv_base, CV_BGR2HSV);

calcHist(&hsv_base, 1, channels, Mat(), hist_base, 2, histSize, range);

normalize(hist_base, hist_base, 0, 1, NORM_MINMAX);

hist_bases.push_back(hist_base);

}

else

{

hist_bases.push_back(Mat());

}

}

double similarity = 0;

vector merged;//是否合并的標(biāo)志位

for (size_t i = 0; i < hist_bases.size(); i++)

{

for (size_t j = i+1; j < hist_bases.size(); j++)

{

if (!merged[j])//未合并的區(qū)域進(jìn)行相似性判斷

{

if (hist_bases[i].dims > 0 && hist_bases[j].dims > 0)//這里維數(shù)判斷沒(méi)必要,直接用個(gè)data就可以了

{

similarity = compareHist(hist_bases[i], hist_bases[j], HISTCMP_BHATTACHARYYA);

if (similarity > 0.8)

{

merged[j] = true;//被合并的區(qū)域標(biāo)志位true

if (i != j)//這里沒(méi)必要,i不可能等于j

{

newNumSeg --;//分割部分減少

for (size_t p = 0; p < segments.rows; p++)

{

for (size_t k = 0; k < segments.cols; k++)

{

int index = segments.at(p, k);

if (index == j) segments.at(p, k) = i;

}

}

}

}

}

}

}

}

numSeg = newNumSeg;//返回合并之后的區(qū)域數(shù)量

}

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • OpenCV
    +關(guān)注

    關(guān)注

    29

    文章

    623

    瀏覽量

    41177

原文標(biāo)題:分水嶺算法(理論+opencv實(shí)現(xiàn))

文章出處:【微信號(hào):AI_shequ,微信公眾號(hào):人工智能愛(ài)好者社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    關(guān)于分水嶺的圖像分割求指點(diǎn)

    `我想對(duì)這幅圖像中的水稻進(jìn)行圖像分割,采取了基于控制標(biāo)記的距離變換分水嶺分割程序如下rgb = imread('C:UserschenxuanDesktop稻子原圖.jpg&
    發(fā)表于 08-27 13:46

    【HiSpark IPC DIY Camera試用連載 】第三篇 分水嶺算法測(cè)試

    自己唯一的編號(hào),輪廓的定位可以通過(guò)Opencv中findContours方法實(shí)現(xiàn),這個(gè)是執(zhí)行 分水嶺之前的要求。接下來(lái)執(zhí)行分水嶺會(huì)發(fā)生什么呢?算法
    發(fā)表于 01-21 23:38

    分水嶺算法在重疊細(xì)胞圖象分割中的應(yīng)用

    分水嶺算法是一種廣泛使用的分割方法,將其用于細(xì)胞圖象分割可以克服由于細(xì)胞交疊造成的圖象分析困難,但缺陷在于它的過(guò)分割結(jié)果。本文給出一種針對(duì)分水嶺過(guò)分割問(wèn)題的解
    發(fā)表于 06-26 08:31 ?24次下載

    多晶硅“門(mén)檻”定調(diào):2010或成行業(yè)分水嶺

    多晶硅“門(mén)檻”定調(diào):2010或成行業(yè)分水嶺   山雨欲來(lái),一場(chǎng)多晶硅行業(yè)的政策風(fēng)暴正在醞釀。   近日,記者獨(dú)家獲
    發(fā)表于 02-01 10:04 ?520次閱讀

    分水嶺算法_《OpenCV3編程入門(mén)》書(shū)本配套源代碼

    OpenCV3編程入門(mén)》書(shū)本配套源代碼:分水嶺算法
    發(fā)表于 06-06 15:39 ?8次下載

    OpenCV3編程入門(mén)-源碼例程全集-分水嶺算法

    OpenCV3編程入門(mén)-源碼例程全集-分水嶺算法,感興趣的小伙伴們可以瞧一瞧。
    發(fā)表于 09-18 16:55 ?0次下載

    基于分水嶺算法的尿沉渣圖像處理方法研究_逄涵涵

    基于分水嶺算法的尿沉渣圖像處理方法研究_逄涵涵
    發(fā)表于 03-17 09:41 ?2次下載

    一種新的彩色圖像分割算法

    本文提出一種新的結(jié)合分水嶺與種子區(qū)域生成、區(qū)域合并的彩色圖像分割算法。首先將RGB顏色空間轉(zhuǎn)換成HSI間,應(yīng)用分水嶺算法對(duì)圖像進(jìn)行初始化分割,形成過(guò)分割效果。接著基于
    發(fā)表于 12-14 14:41 ?1次下載
    一種新的彩色圖像分割<b class='flag-5'>算法</b>

    2018年將為全球供應(yīng)鏈數(shù)碼化分水嶺

    據(jù)報(bào)導(dǎo),隨著企業(yè)積極響應(yīng)政府和政府間組織的新倡議,2018年將成為全球供應(yīng)鏈數(shù)碼化的分水嶺。而能促成全球供應(yīng)鏈數(shù)碼化的關(guān)鍵,可從下面幾格趨勢(shì)來(lái)觀察:
    發(fā)表于 01-22 08:43 ?1047次閱讀

    中國(guó)互聯(lián)網(wǎng)未來(lái)5年趨勢(shì)是如何的?分水嶺大時(shí)代到來(lái)。

    報(bào)告指出,分水嶺大時(shí)代即將到來(lái):“分水嶺”將成為未來(lái)五年中國(guó)互聯(lián)網(wǎng)的關(guān)鍵詞;從淺水區(qū)向深水區(qū)過(guò)度,引發(fā)競(jìng)爭(zhēng)格局的強(qiáng)弱勢(shì)轉(zhuǎn)化;分水嶺區(qū)不存在直道競(jìng)爭(zhēng),冷靜和變化成為主旋律。
    的頭像 發(fā)表于 09-09 09:18 ?6614次閱讀

    國(guó)產(chǎn)手機(jī)市場(chǎng)的爭(zhēng)奪還在繼續(xù) 華為小米手機(jī)業(yè)務(wù)走到了分水嶺

    2018年對(duì)小米和華為來(lái)說(shuō)是一個(gè)轉(zhuǎn)折點(diǎn)。國(guó)產(chǎn)手機(jī)市場(chǎng)的爭(zhēng)奪還在繼續(xù),但是兩家的業(yè)務(wù)布局在悄然變化,手機(jī)業(yè)務(wù)對(duì)集團(tuán)的戰(zhàn)略支撐,走到了分水嶺
    發(fā)表于 12-19 14:10 ?1189次閱讀

    “史上最嚴(yán)”能效令發(fā)布 空調(diào)市場(chǎng)即將迎來(lái)分水嶺

    近日,隨著“史上最嚴(yán)”空調(diào)能效標(biāo)準(zhǔn)發(fā)布這一權(quán)威消息不脛而走,深陷價(jià)格戰(zhàn)泥潭的空調(diào)市場(chǎng)即將迎來(lái)分水嶺。記者從相關(guān)渠道獲悉,長(zhǎng)虹空調(diào)將繼主推的超一級(jí)能效產(chǎn)品Q5Ks之后,即可發(fā)布兩款新品——Q5A好睡眠空調(diào)和Q5D AI舒適空調(diào),搶占能效調(diào)整帶來(lái)的最大一波變頻紅利。
    發(fā)表于 01-06 10:05 ?524次閱讀

    站在從4G向5G跨越的分水嶺上,四大廠商2019年的業(yè)績(jī)表現(xiàn)如何

    對(duì)于通信行業(yè)而言,2019年是真正意義上的5G元年,雖然全球范圍內(nèi)的5G網(wǎng)絡(luò)建設(shè)仍未大規(guī)模啟動(dòng),但隨著韓國(guó)、美國(guó)和中國(guó)等主要市場(chǎng)相繼宣布5G商用,2019年已成為通信行業(yè)從4G向5G跨越的分水嶺。
    的頭像 發(fā)表于 04-10 15:19 ?2300次閱讀
    站在從4G向5G跨越的<b class='flag-5'>分水嶺</b>上,四大廠商2019年的業(yè)績(jī)表現(xiàn)如何

    超全分水嶺算法匯總

    超全分水嶺算法匯總
    發(fā)表于 10-08 10:27 ?0次下載

    opencv實(shí)戰(zhàn)——機(jī)器視覺(jué)檢測(cè)和計(jì)數(shù)

    由于之前網(wǎng)購(gòu)的維生素片,有時(shí)候忘了今天有沒(méi)有吃過(guò),就想對(duì)瓶子里的藥片計(jì)數(shù)...在學(xué)習(xí)opencv以后,希望實(shí)現(xiàn)對(duì)于維生素片分割計(jì)數(shù)算法。本次實(shí)戰(zhàn)在基于形態(tài)學(xué)的基礎(chǔ)上又衍生出基于距離變換的分水嶺
    的頭像 發(fā)表于 03-03 11:54 ?1879次閱讀