網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
通常提取物體的輪廓時(shí),圖像都存在噪聲,提取效果并不理想。如提取下圖的輪廓時(shí),
提取代碼:
import cv2
img = cv2.imread("mouse.png")
cv2.imshow("origin",img)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,binary = cv2.threshold(gray,128,255,cv2.THRESH_BINARY)
cv2.imshow("binary",binary)
contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img,contours,-1,(0,0,255),3)
cv2.imshow("result", img)
cv2.waitKey(0)
?提取效果:
可以看出存在非常嚴(yán)重的噪聲干擾。因此,提取輪廓之前需要過(guò)濾噪聲的干擾。
首先,進(jìn)行對(duì)圖像進(jìn)行均值濾波(低通濾波),去除噪聲
blured = cv2.blur(img,(5,5))
cv2.imshow("blur",blured)
?
使用floodfill來(lái)去掉目標(biāo)周?chē)谋尘埃汉樘畛漕?lèi)始于ps的魔棒工具,這里用來(lái)清除背景。
mask = np.zeros((h+2, w+2), np.uint8) #掩碼長(zhǎng)和寬都比輸入圖像多兩個(gè)像素點(diǎn),泛洪填充不會(huì)超出掩碼的非零邊緣
#進(jìn)行泛洪填充
cv2.floodFill(blured, mask, (10,10), (255,255,255), (2,2,2),(3,3,3),8)
cv2.imshow("floodfill", blured)
??floodFill函數(shù)解析
- img:為待使用泛洪算法的圖像
- mask:為掩碼層,使用掩碼可以規(guī)定是在哪個(gè)區(qū)域使用該算法,如果是對(duì)于完整圖像都要使用,則掩碼層大小為原圖行數(shù)+2,列數(shù)+2.是一個(gè)二維的0矩陣,邊緣一圈會(huì)在使用算法是置為1。而只有對(duì)于掩碼層上對(duì)應(yīng)為0的位置才能泛洪,所以掩碼層初始化為0矩。【dtype:np.uint8】
- seed:為泛洪算法的種子點(diǎn),也是根據(jù)該點(diǎn)的像素判斷決定和其相近顏色的像素點(diǎn),是否被泛洪處理。
- newvalue:是對(duì)于泛洪區(qū)域新賦的值(B,G,R)
- (loDiff1,loDiff2,loDiff3):是相對(duì)于seed種子點(diǎn)像素可以往下的像素值,即seed(B0,G0,R0),泛洪區(qū)域下界為(B0-loDiff1,G0-loDiff2,R0-loDiff3)
- (upDiff1,upDiff2,upDiff3):是相對(duì)于seed種子點(diǎn)像素可以往上的像素值,即seed(B0,G0,R0),泛洪區(qū)域上界為(B0+upDiff1,G0+upDiff2,R0+upDiff3)
- flag:為泛洪算法的處理模式:
- ? ? 低八位 控制算法的連通性,是以seed點(diǎn)為中心,接著判斷周?chē)膸讉€(gè)像素點(diǎn),再將泛洪區(qū)域像素點(diǎn)周?chē)膸讉€(gè)像素點(diǎn)進(jìn)行考慮。 一般為4,8;默認(rèn)為4
- ? ? 中間八位 與掩碼層賦值密切相關(guān),一般使用(255<<8)使中間8位全位1,則值為255,也就是掩碼層對(duì)應(yīng)原圖的泛洪區(qū)域的部分被由原來(lái)的初值0賦值成255,如果中間8位為0,則賦值為1.
- ? ? 高八位 由opencv宏參數(shù)指定
- cv2.FLOODFILL_FIXED_RANGE:改變圖像,填充newvalue
- cv2.FLOODFILL_MASK_ONLY:不改變?cè)瓐D像,也就是newvalue參數(shù)失去作用,而是改變對(duì)應(yīng)區(qū)域的掩碼,設(shè)為中間八位的值
然后轉(zhuǎn)換成灰度圖
gray = cv2.cvtColor(blured,cv2.COLOR_BGR2GRAY)
cv2.imshow("gray", gray)
此時(shí)目標(biāo)圖像周?chē)袑?xiě)不光滑,還有一些噪聲,因此進(jìn)行開(kāi)閉運(yùn)算,得到比較光滑的目標(biāo)
#定義結(jié)構(gòu)元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(50, 50))
#開(kāi)閉運(yùn)算,先開(kāi)運(yùn)算去除背景噪聲,再繼續(xù)閉運(yùn)算填充目標(biāo)內(nèi)的孔洞
opened = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)
closed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, kernel)
cv2.imshow("closed", closed)
接著轉(zhuǎn)換成二值圖以便于獲取圖像的輪廓
最后進(jìn)行輪廓提取,抓取到目標(biāo)
#找到輪廓
_,contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#繪制輪廓
cv2.drawContours(img,contours,-1,(0,0,255),3)
#繪制結(jié)果
cv2.imshow("result", img)
全部代碼:
#coding=utf-8
import cv2
import numpy as np
img = cv2.imread("temp.jpg") #載入圖像
h, w = img.shape[:2] #獲取圖像的高和寬
cv2.imshow("Origin", img) #顯示原始圖像
blured = cv2.blur(img,(5,5)) #進(jìn)行濾波去掉噪聲
cv2.imshow("Blur", blured) #顯示低通濾波后的圖像
mask = np.zeros((h+2, w+2), np.uint8) #掩碼長(zhǎng)和寬都比輸入圖像多兩個(gè)像素點(diǎn),滿(mǎn)水填充不會(huì)超出掩碼的非零邊緣
#進(jìn)行泛洪填充
cv2.floodFill(blured, mask, (w-1,h-1), (255,255,255), (2,2,2),(3,3,3),8)
cv2.imshow("floodfill", blured)
#得到灰度圖
gray = cv2.cvtColor(blured,cv2.COLOR_BGR2GRAY)
cv2.imshow("gray", gray)
#定義結(jié)構(gòu)元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(50, 50))
#開(kāi)閉運(yùn)算,先開(kāi)運(yùn)算去除背景噪聲,再繼續(xù)閉運(yùn)算填充目標(biāo)內(nèi)的孔洞
opened = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)
closed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, kernel)
cv2.imshow("closed", closed)
#求二值圖
ret, binary = cv2.threshold(closed,250,255,cv2.THRESH_BINARY)
cv2.imshow("binary", binary)
#找到輪廓
_,contours, hierarchy = cv2.findContours(binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#繪制輪廓
cv2.drawContours(img,contours,-1,(0,0,255),3)
#繪制結(jié)果
cv2.imshow("result", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
總結(jié)
原文鏈接:https://blog.csdn.net/wzw12315/article/details/120882364
相關(guān)推薦
- 2024-04-02 docker開(kāi)機(jī)自啟設(shè)置
- 2022-09-06 本地搭建minio文件服務(wù)器(使用bat腳本啟動(dòng))的方法_服務(wù)器其它
- 2022-04-07 Kotlin原理詳析之拓展函數(shù)_Android
- 2022-03-20 詳解C語(yǔ)言的預(yù)處理效果_C 語(yǔ)言
- 2023-09-12 SpringBoot整合MQTT(MqttClient)
- 2022-12-16 python靜態(tài)web服務(wù)器實(shí)現(xiàn)方法及代碼詳解_python
- 2022-10-10 GO必知必會(huì)的常見(jiàn)面試題匯總_Golang
- 2022-11-21 解析Rust?struct?中的生命周期_Rust語(yǔ)言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支