欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++中實現(xiàn)OpenCV圖像分割與分水嶺算法

 更新時間:2021年06月08日 11:31:25   作者:進擊的Explorer  
分水嶺算法是一種常用的圖像區(qū)域分割法,本文主要介紹了OpenCV圖像分割與分水嶺算法,使用C++實現(xiàn),具有一定的參考價值,感興趣的可以了解一下

分水嶺算法是一種圖像區(qū)域分割法,在分割的過程中,它會把跟臨近像素間的相似性作為重要的參考依據(jù),從而將在空間位置上相近并且灰度值相近的像素點互相連接起來構(gòu)成一個封閉的輪廓,封閉性是分水嶺算法的一個重要特征。

API介紹

void watershed( InputArray image, InputOutputArray markers );

參數(shù)說明:

  • image: 必須是一個8bit 3通道彩色圖像矩陣序列
  • markers: 在執(zhí)行分水嶺函數(shù)watershed之前,必須對第二個參數(shù)markers進行處理,它應該包含不同區(qū)域的輪廓,每個輪廓有一個自己唯一的編號,輪廓的定位可以通過Opencv中findContours方法實現(xiàn),這個是執(zhí)行分水嶺之前的要求。算法會根據(jù)markers傳入的輪廓作為種子(也就是所謂的注水點),對圖像上其他的像素點根據(jù)分水嶺算法規(guī)則進行判斷,并對每個像素點的區(qū)域歸屬進行劃定,直到處理完圖像上所有像素點。而區(qū)域與區(qū)域之間的分界處的值被置為“-1”,以做區(qū)分。

我們將一個如何使用距離變換和分水嶺分割相互接觸的物體的例子。

考慮一下下面的硬幣圖像,這些硬幣相互接觸。即使你去閾值化它,它也會互相碰觸。

CSDN圖標

我們從找到硬幣的大概估計值開始。為此,我們可以利用大津的二值化。

#include<iostream>
#include<opencv2\opencv.hpp>

using namespace std;
using namespace cv;

int main() {
	Mat gray, thresh;
	Mat img = imread("coins.jpg");
	cvtColor(img, gray, COLOR_BGR2GRAY);
	threshold(gray, thresh, 0, 255, THRESH_BINARY_INV+CV_THRESH_OTSU);

	imshow("Otst閾值圖像", thresh);
	waitKey(0);
	return 0;
}

閾值后的圖像如下所示:

CSDN圖標

現(xiàn)在需要去除圖像中任何微小的白色噪聲。為此,我們可以使用形態(tài)開操作。為了去除物體上的任何小洞,我們可以使用形態(tài)閉操作。所以,現(xiàn)在我們可以確定的是,靠近物體中心的區(qū)域是前景,遠離物體的區(qū)域是背景。只有我們不確定的區(qū)域是硬幣的邊界區(qū)域。

所以我們需要提取我們確定是硬幣的區(qū)域。侵蝕去除邊界像素。所以不管剩下多少,我們都能確定是硬幣。如果物體不互相接觸,那就可以了。但是由于它們彼此接觸,另一個好的選擇是找到距離變換并應用適當?shù)拈撝?。接下來我們需要找到我們確信不是硬幣的區(qū)域。為此,我們擴展了結(jié)果。膨脹將物體邊界增加到背景。通過這種方式,我們可以確保結(jié)果中的任何背景區(qū)域都是真正的背景,因為邊界區(qū)域。

CSDN圖標

剩下的區(qū)域是我們不知道的,無論是硬幣還是背景。分水嶺算法應該能找到它。這些區(qū)域通常圍繞著硬幣的邊界,也就是前景和背景相遇的地方(甚至是兩個不同的硬幣相遇的地方)。我們稱之為邊界。用sure_fg 面積減去sure_bg面積可得。

Mat opening; Mat sure_bg;
Mat sure_fg; Mat unknow;
Mat dist_transform;
double maxValue;
// noise removal
Mat kernel = Mat::ones(3, 3, CV_8U);
morphologyEx(thresh, opening, MORPH_OPEN, kernel);

// sure background area
dilate(opening, sure_bg, kernel, Point(-1, -1), 3);

// Finding sure foreground area
distanceTransform(opening, dist_transform, DIST_L2, 5);
minMaxLoc(dist_transform, 0, &maxValue, 0, 0);
threshold(dist_transform, sure_fg, 0.7*maxValue, 255, 0);

// Finding unknown region
sure_fg.convertTo(sure_fg, CV_8U);
subtract(sure_bg, sure_fg, unknow);

看到結(jié)果。在閾值圖像中,我們得到了一些區(qū)域的硬幣,我們確定這些硬幣是獨立的。(在某些情況下,你可能只對前景分割感興趣,而對相互接觸的對象的分割不感興趣。在這種情況下,你不需要使用距離變換,只要侵蝕就足夠了。侵蝕只是提取前景區(qū)域的另一種方法,僅此而已。)

CSDN圖標 CSDN圖標

現(xiàn)在我們可以確定哪些是硬幣區(qū)域,哪些是背景等等。因此我們創(chuàng)建了marker(它是一個與原始圖像大小相同的數(shù)組,但是使用int32數(shù)據(jù)類型),并在其中標記區(qū)域。我們確定的區(qū)域(無論是前景還是背景)被標記為任何正整數(shù),但是不同的整數(shù),而我們不確定的區(qū)域則被保留為0。為此,我們使用了connectedComponents()。它用0標記圖像的背景,然后用從1開始的整數(shù)標記其他對象。

但是我們知道,如果將background標記為0,watershed將認為它是未知區(qū)域。所以我們要用不同的整數(shù)來標記它。相反,我們將標記未知區(qū)域,由unknown定義,為0。

// Marker labelling
Mat markers;
connectedComponents(sure_fg, markers);

// Add one to all labels so that sure background is not 0, but 1
markers = markers + 1;

// Now, mark the region of unknown with zero
markers.setTo(0, unknow);

現(xiàn)在我們的標記圖像準備好了。到了最后一步,應用分水嶺。然后修改標記圖像。邊界區(qū)域?qū)擞洖?1。

Mat marker;
Mat mask;
watershed(img, markers);
compare(markers, -1, mask, CMP_EQ);
img.setTo(Scalar(0, 0, 255), mask);

參見下面的結(jié)果。對于一些硬幣,它們接觸的區(qū)域被正確分割,而對于另一些硬幣,它們沒有被分割。

CSDN圖標 CSDN圖標

到此這篇關于C++中實現(xiàn)OpenCV圖像分割與分水嶺算法的文章就介紹到這了,更多相關OpenCV圖像分割與分水嶺算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • linux中查詢dns示例

    linux中查詢dns示例

    這篇文章主要介紹了linux中查詢dns示例,需要的朋友可以參考下
    2014-04-04
  • 帶你粗略了解C++流的讀寫文件

    帶你粗略了解C++流的讀寫文件

    這篇文章主要為大家總結(jié)了C++中輸入輸出流及文件流操作,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能給你帶來幫助
    2021-08-08
  • C++中順序表操作的示例代碼

    C++中順序表操作的示例代碼

    這篇文章主要為大家詳細介紹了C++中順序表的基礎操作的相關代碼,主要有順序表的輸出、插入和刪除數(shù)據(jù)等,感興趣的小伙伴可以了解一下
    2022-10-10
  • C++實踐數(shù)組類運算的實現(xiàn)參考

    C++實踐數(shù)組類運算的實現(xiàn)參考

    今天小編就為大家分享一篇關于C++實踐數(shù)組類運算的實現(xiàn)參考,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • C++ LARGE_INTEGER解析與使用案例詳解

    C++ LARGE_INTEGER解析與使用案例詳解

    這篇文章主要介紹了C++ LARGE_INTEGER解析與使用案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 使用C語言實現(xiàn)12種排序方法

    使用C語言實現(xiàn)12種排序方法

    這篇文章主要介紹了用C語言完整實現(xiàn)12種排序方法,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-12-12
  • C語言中實現(xiàn)協(xié)程案例

    C語言中實現(xiàn)協(xié)程案例

    這篇文章主要介紹了C語言中實現(xiàn)協(xié)程案例,本文通過將協(xié)程與線程和異步回調(diào)進行對比,以及具體實現(xiàn)案例,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 項目之C++如何實現(xiàn)數(shù)據(jù)庫連接池

    項目之C++如何實現(xiàn)數(shù)據(jù)庫連接池

    這篇文章主要介紹了項目之C++如何實現(xiàn)數(shù)據(jù)庫連接池問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • C++實現(xiàn)修改函數(shù)代碼HOOK的封裝方法

    C++實現(xiàn)修改函數(shù)代碼HOOK的封裝方法

    這篇文章主要介紹了C++實現(xiàn)修改函數(shù)代碼HOOK的封裝方法,有助于深入了解C++的HOOK原理,需要的朋友可以參考下
    2014-10-10
  • VScode搭建C/C++開發(fā)環(huán)境的詳細過程

    VScode搭建C/C++開發(fā)環(huán)境的詳細過程

    最近迷上了vscode,小巧美觀,最主要的是全平臺,但是vscode并不是ide,必須得自己配置環(huán)境,下面這篇文章主要給大家介紹了關于VScode搭建C/C++開發(fā)環(huán)境的詳細過程,需要的朋友可以參考下
    2023-06-06

最新評論