python圖像分割算法_OpenCV-Python 圖像分割與Watershed算法 | 三十四

目標

在本章中,

我們將學習使用分水嶺算法實現基于標記的圖像分割

我們將看到:cv.watershed()

理論

任何灰度圖像都可以看作是一個地形表面,其中高強度表示山峰,低強度表示山谷。你開始用不同顏色的水(標簽)填充每個孤立的山谷(局部最小值)。隨著水位的上升,根據附近的山峰(坡度),來自不同山谷的水明顯會開始合并,顏色也不同。為了避免這種情況,你要在水融合的地方建造屏障。你繼續填滿水,建造障礙,直到所有的山峰都在水下。然后你創建的屏障將返回你的分割結果。這就是Watershed背后的“思想”。你可以訪問Watershed的CMM網頁,了解它與一些動畫的幫助。

但是這種方法會由于圖像中的噪聲或其他不規則性而產生過度分割的結果。因此OpenCV實現了一個基于標記的分水嶺算法,你可以指定哪些是要合并的山谷點,哪些不是。這是一個交互式的圖像分割。我們所做的是給我們知道的對象賦予不同的標簽。用一種顏色(或強度)標記我們確定為前景或對象的區域,用另一種顏色標記我們確定為背景或非對象的區域,最后用0標記我們不確定的區域。這是我們的標記。然后應用分水嶺算法。然后我們的標記將使用我們給出的標簽進行更新,對象的邊界值將為-1。

代碼

下面我們將看到一個有關如何使用距離變換和分水嶺來分割相互接觸的對象的示例。

考慮下面的硬幣圖像,硬幣彼此接觸。即使你設置閾值,它也會彼此接觸。

20200123193207330.jpeg

我們先從尋找硬幣的近似估計開始。因此,我們可以使用Otsu的二值化。

import numpy as np

import cv2 as cv

from matplotlib import pyplot as plt

img = cv.imread('coins.png')

gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)

ret, thresh = cv.threshold(gray,0,255,cv.THRESH_BINARY_INV cv.THRESH_OTSU)

20200123193207487.jpeg

現在我們需要去除圖像中的任何白點噪聲。為此,我們可以使用形態學擴張。要去除對象中的任何小孔,我們可以使用形態學侵蝕。因此,現在我們可以確定,靠近對象中心的區域是前景,而離對象中心很遠的區域是背景。我們不確定的唯一區域是硬幣的邊界區域。

因此,我們需要提取我們可確定為硬幣的區域。侵蝕會去除邊界像素。因此,無論剩余多少,我們都可以肯定它是硬幣。如果物體彼此不接觸,那將起作用。但是,由于它們彼此接觸,因此另一個好選擇是找到距離變換并應用適當的閾值。接下來,我們需要找到我們確定它們不是硬幣的區域。為此,我們擴張了結果。膨脹將對象邊界增加到背景。這樣,由于邊界區域已刪除,因此我們可以確保結果中背景中的任何區域實際上都是背景。參見下圖。

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZlbmRvdWFpbmk=,size_16,color_FFFFFF,t_70

剩下的區域是我們不知道的區域,無論是硬幣還是背景。分水嶺算法應該找到它。這些區域通常位于前景和背景相遇(甚至兩個不同的硬幣相遇)的硬幣邊界附近。我們稱之為邊界。可以通過從sure_bg區域中減去sure_fg區域來獲得。

# 噪聲去除

kernel = np.ones((3,3),np.uint8)

opening = cv.morphologyEx(thresh,cv.MORPH_OPEN,kernel, iterations = 2)

# 確定背景區域

sure_bg = cv.dilate(opening,kernel,iterations=3)

# 尋找前景區域

dist_transform = cv.distanceTransform(opening,cv.DIST_L2,5)

ret, sure_fg = cv.threshold(dist_transform,0.7*dist_transform.max(),255,0)

# 找到未知區域

sure_fg = np.uint8(sure_fg)

unknown = cv.subtract(sure_bg,sure_fg)

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

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZlbmRvdWFpbmk=,size_16,color_FFFFFF,t_70

現在我們可以確定哪些是硬幣的區域,哪些是背景。因此,我們創建了標記(它的大小與原始圖像的大小相同,但具有int32數據類型),并標記其中的區域。我們肯定知道的區域(無論是前景還是背景)都標有任何正整數,但是帶有不同的整數,而我們不確定的區域則保留為零。為此,我們使用cv.connectedComponents()。它用0標記圖像的背景,然后其他對象用從1開始的整數標記。

但是我們知道,如果背景標記為0,則分水嶺會將其視為未知區域。所以我們想用不同的整數來標記它。相反,我們將未知定義的未知區域標記為0。

# 類別標記

ret, markers = cv.connectedComponents(sure_fg)

# 為所有的標記加1,保證背景是0而不是1

markers = markers 1

# 現在讓所有的未知區域為0

markers[unknown==255] = 0

參見JET colormap中顯示的結果。深藍色區域顯示未知區域。當然,硬幣的顏色不同。剩下,肯定為背景的區域顯示在較淺的藍色,跟未知區域相比。

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZlbmRvdWFpbmk=,size_16,color_FFFFFF,t_70

現在我們的標記已準備就緒。現在是最后一步的時候了,使用分水嶺算法。然后標記圖像將被修改。邊界區域將標記為-1。

markers = cv.watershed(img,markers)

img[markers == -1] = [255,0,0]

請參閱下面的結果。對某些硬幣,它們接觸的區域被正確地分割,而對于某些硬幣,卻不是。

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZlbmRvdWFpbmk=,size_16,color_FFFFFF,t_70

附加資源

練習

OpenCV samples has an interactive sample on watershed segmentation, watershed.py. Run it, Enjoy it, then learn it.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/539426.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/539426.shtml
英文地址,請注明出處:http://en.pswp.cn/news/539426.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux dns 問題嗎,Linux下DNS的問題

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓Nov 9 06:36:22 BJ-linux kernel: end_request: I/O error, dev fd0, sector 0Nov 9 06:36:22 BJ-linux kernel: end_request: I/O error, dev fd0, sector 0Nov 9 06:37:06 BJ-linux system-config-network[4031]: - //etc/…

NEO從源碼分析看共識協議

2019獨角獸企業重金招聘Python工程師標準>>> 0x00 概論 不同于比特幣使用的工作量證明(PoW)來實現共識,NEO提出了DBFT共識算法。DBFT改良自股權證明算法(PoS),我沒有具體分析過PoS的源碼&#x…

oracle實現id自增和設置主鍵

1、關于主鍵:在建表時指定primary key字句即可: create table test( id number(6) primary key, name varchar2(30) ); 如果是對于已經建好的表,想增加主鍵約束,則類似語法: alter table test add constraint p…

python scrapy框架基如何實現多線程_Python實現在線程里運行scrapy的方法

本文實例講述了Python實現在線程里運行scrapy的方法。分享給大家供大家參考。具體如下: 如果你希望在一個寫好的程序里調用scrapy,就可以通過下面的代碼,讓scrapy運行在一個線程里。 """ Code to run Scrapy crawler in a thr…

怎樣在linux系統上安裝r,Linux系統之路——如何在CentOS7.2安裝R(示例代碼)

使用ubuntu的小伙伴們直接使用命令sudo apt-get installr-base-dev或者r-base搞定。然而對于使用centos的我卻一直卡在安裝這一步,十分的悲催,只有羨慕的份,但也不至于在linux上使用不上R。辦法還是有的,自己總結出兩種方法&#…

自定義實現棧的功能

棧的定義:棧是一個數據集合,我們可以吧它理解為是一個只能在一端進行插入或者刪除的列表。棧的特點:先進后出 Stack() 建立一個空的棧對象push() 吧一個元素添加到棧的最頂層pop() 刪除棧最頂層的元素,并返回這個元素gettop() 取棧…

mybatis循環map的一些技巧

<foreach>標簽的用法&#xff1a; 六個參數&#xff1a; collection&#xff1a;要循環的集合 index&#xff1a;循環索引&#xff08;不知道啥用。。&#xff09; item&#xff1a;集合中的一個元素&#xff08;item和collection&#xff0c;按foreach循環理解&#xff…

linux部署node web,nodejs怎么部署到Linux上?

nodejs怎么部署到Linux上&#xff1f;下面本篇文章就來給大家介紹一下在Linux上部署nodejs的方法&#xff0c;希望對大家有所幫助。nodejs部署到Linux上的方法如下&#xff1a;(建議先安裝xshell和xftp)1、到nodejs官網下載壓縮包(選擇合適自己系統的版本)&#xff0c;放到Linu…

python樹莓派 是什么_用樹莓派和Python給你的植物澆水

我想指出&#xff0c;我絕不是電子學專家。如果你讓我制作一個電路圖或者解釋某件電子產品工作原理的細節&#xff0c;我會一無所知。在生活中&#xff0c;我對電力的工作原理有了基本的了解&#xff0c;我只是胡亂擺弄了一下電子元件就完成了這個工程。話雖如此&#xff0c;當…

htmlspecialchars() 函數過濾XSS的問題

htmlspecialchars()函數的功能如下&#xff1a; htmlspecialchars() 函數把預定義的字符轉換為 HTML 實體。 預定義的字符是&#xff1a; & &#xff08;和號&#xff09;成為 &" &#xff08;雙引號&#xff09;成為 " &#xff08;單引號&#xff09;成為 …

c語言中 字母對應的數值,C語言編程:求下式中每個字母所代表的數字

編寫程序求解下式中各字母所代表的數字&#xff0c;不同的字母代表不同的數字。PEAR- ARA PEA*問題分析與算法設計類似的問題從計算機算法的角度來說是比較簡單的&#xff0c;可以采用最常見的窮舉方法解決。程序中采用循環窮舉每個字母所可能代表的數字&#xff0c;然后將字母…

用mac的python寫網絡爬蟲_在mac下使用python抓取數據

2015已經過去&#xff0c;這是2016的第一篇博文&#xff01; 祝大家新年快樂&#xff01; 但是我還有好多期末考試&#xff01; 還沒開始復習&#xff0c;唉&#xff0c;一把辛酸淚&#xff01; 最近看了一遍彥祖的文章叫做 所以自己也想小試牛刀.于是便開始動手寫,但初次接觸,…

運輸配送信息Delivery_Information

為什么80%的碼農都做不了架構師&#xff1f;>>> 運輸配送信息Delivery_Information 金銀倉會選用以下運輸公司&#xff0c;為客戶配送磁磚傢俬潔具&#xff1a; 佛山冠昌達中港運輸&#xff08;散貨或包車&#xff0c;近佛山石灣的磁磚倉庫&#xff0c;近樂從傢俬城…

linux的 dev vdal,RAZVOJ DELA NA DALJAVO V SLOVENIJI

摘要&#xff1a;V diplomskem delu bomo raziskovali razvoj dela na daljavo v Sloveniji. Na? poglavitni cilj je prikazati ?irjenje teledela v Sloveniji. Drugod po Evropi se ?e vrsto let uveljavlja tudi ta vrsta opravljanja dela, pri nas pa manj. O tem lah…

Spring+SpringMVC+Mybatis 多數據源整合

原文地址&#xff1a;http://blog.csdn.net/q908555281/article/details/50316137 ----------------------------------- 此篇文章是基于Spring3.0和mybatis3.2的總體大概流程 &#xff1a;1. 拷貝所需jar 2.寫一個數據庫切換的工具類&#xff1a;DataSourceContextHolder&am…

查看mysql sql執行器優化后的sql

EXPLAIN EXTENDED select s.* from student s where s.sid in ( select sid from sc where sc.cid 0 and sc.score 100); show WARNINGS;

git ssh拉取代碼_win10下git初始安裝及配置工作

git安裝從https://git-scm.com/https://git-scm.com/download/win 中下載安裝包&#xff0c;點擊exe文件運行&#xff0c;選擇安裝路徑即可安裝。git配置初次運行git前的配置&#xff0c;新建文件夾1、 新建一個文件夾&#xff0c;用來存放代碼的文件夾---2、 打開文件夾&#…

用ABAP 生成二維碼 QR Code

除了使用我的這篇blogStep by step to create QRCode in ABAP Webdynpro提到的使用ABAP webdynpro生成二維碼之外&#xff0c;也可以通過使用二維碼在線生成網站提供的service來生成二維碼。 二維碼在線生成網站&#xff1a; www.makepic.com/qrcode.php 在網頁上輸入要生成的二…

c語言不用第三變量,C語言中幾種不用第三變量交換兩值的方法

int main(){int a3,b4;int *p(int *)malloc(sizeof(int));*p3;int *q(int *)malloc(sizeof(int));*q4;int a24,b27;printf("***位運算****/n");printf("轉換前&#xff1a;%d %d/n",a,b);a^b^a^b;printf("轉換后&#xff1a;%d %d/n",a,b);print…

聯想m7400pro清零方法_聯想打印機怎么清零 聯想打印機清零方法【教程】

今天小編為讀者挑選出了聯想 打印機 部分機型的清零方式&#xff0c;希望閱讀完這篇文章能幫助到各位。LJ3010A、LJ3116A、LJ3220A清零方式先點擊控制面板上的“聯機”按鈕&#xff0c;讓打印機處于脫機狀態&#xff0c;再點擊“執行”按鈕進行打印。先點擊控制面板上的“聯機”…