背景介紹
測試圖如下,圖中有個別米粒相互粘連,本文主要演示如何使用OpenCV用兩種不同方法將其分割并計數。

方法一:基于分水嶺算法
基于分水嶺算法分割步驟如下:
【1】高斯濾波 + 二值化 +開運算
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray,(5,5),0) ret, binary= cv2.threshold(gray, 115, 255, cv2.THRESH_BINARY) kernel = np.ones((5, 5), np.uint8) binary=cv2.morphologyEx(binary,cv2.MORPH_OPEN,kernel,iterations=1) cv2.imshow('thres', binary)

【2】距離變換 + 提取前景
dist = cv2.distanceTransform(binary, cv2.DIST_L2, 3)
dist_out = cv2.normalize(dist, 0, 1.0, cv2.NORM_MINMAX)
cv2.imshow('distance-Transform', dist_out * 100)
ret, surface = cv2.threshold(dist_out, 0.35*dist_out.max(), 255, cv2.THRESH_BINARY)
cv2.imshow('surface', surface)
sure_fg = np.uint8(surface)# 轉成8位整型
cv2.imshow('Sure foreground', sure_fg)


【3】標記位置區域
# 未知區域標記為0 markers[unknown == 255] = 0 kernel = np.ones((5, 5), np.uint8) binary = cv2.morphologyEx(binary, cv2.MORPH_DILATE, kernel, iterations=1) unknown = binary - sure_fg cv2.imshow('unknown',unknown)

【4】分水嶺算法分割
markers = cv2.watershed(img, markers=markers) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(markers)
【5】輪廓查找和標記
contours,hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) forcntincontours: M = cv2.moments(cnt) cx = int(M['m10']/M['m00']) cx = int(M['m10']/M['m00']) cy = int(M['m01']/M['m00'])#輪廓重心 cv2.drawContours(img,contours,-1,colors[rd.randint(0,5)],2) cv2.drawMarker(img, (cx,cy),(0,255,0),1,8,2)

方法二:輪廓凸包缺陷方法
基于輪廓凸包缺陷分割步驟如下:
【1】高斯濾波 + 二值化 +開運算
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray,(5,5),0)
ret, binary= cv2.threshold(gray, 115, 255, cv2.THRESH_BINARY)
kernel=np.ones((5,5),np.uint8)
binary=cv2.morphologyEx(binary,cv2.MORPH_OPEN,kernel,iterations=1)
cv2.imshow('thres', binary)

【2】輪廓遍歷 + 篩選輪廓含有凸包缺陷的輪廓
contours,hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
for cnt in contours:
hull = cv2.convexHull(cnt,returnPoints=False)#默認returnPoints=True
defects = cv2.convexityDefects(cnt,hull)
#print defects
pt_list = []
if defects is not None:
flag = False
for i in range(0,defects.shape[0]):
s,e,f,d = defects[i,0]
if d > 4500:
flag = True

【3】將距離d最大的兩個凸包缺陷點連起來,將二值圖中對應的粘連區域分割開,紅色圓標注為分割開的部分
if len(pt_list) > 0:
cv2.line(binary,pt_list[0],pt_list[1],0,2)
cv2.imshow('binary2',binary)


【4】重新查找輪廓并標記結果
contours,hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
for cnt in contours:
try:
M = cv2.moments(cnt)
cx = int(M['m10']/M['m00'])
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])#輪廓重心
cv2.drawContours(img,cnt,-1,colors[rd.randint(0,5)],2)
cv2.drawMarker(img, (cx,cy),(0,0,255),1,8,2)
except:
pass

審核編輯:劉清
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
高斯濾波
+關注
關注
0文章
18瀏覽量
8230 -
OpenCV
+關注
關注
33文章
652瀏覽量
44784
原文標題:實戰 | OpenCV兩種不同方法實現粘連大米分割計數(步驟 + 代碼)
文章出處:【微信號:vision263com,微信公眾號:新機器視覺】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
熱點推薦
兩種LED驅動模式的功能及使用方法
中穎MCU普通LED模塊(非恒流)提供了兩種LED驅動模式:亮滅模式、調光模式。兩種模式的功能及使用方法簡介如下。
發表于 08-26 11:18
?5130次閱讀
兩種verilog語言寫法的實現問題!求解答~
在看verilog代碼時,看到這樣兩種表示方法:一種是:“ wirea;assigna=b;”一種是:“wirea=b;”請教各位大神這兩種
發表于 01-29 14:33
基于LabVIEW的Modbus協議兩種校驗碼的實現方法
基于LabVIEW的Modbus協議兩種校驗碼的實現方法
介紹基于LabVIEW的Modbus協議兩種校驗碼的實現
發表于 10-13 00:08
?4969次閱讀
單片機系統實現延時的兩種方法解析
實現延時通常有兩種方法:一種是硬件延時,要用到定時器/計數器,這種方法可以提高CPU的工作效率,也能做到精確延時;另一
發表于 01-24 17:06
?1.5w次閱讀
Multibool的兩種實現方法詳細資料介紹
介紹了Multibool的兩種實現方法。通過Xilinx Spartan-6 FPGA的Multiboot特性,允許用戶一次將多個配置文件下載入Flash中,根據不同時刻的需求,在不掉電重啟的情況下,從中選擇一個來重配置FPGA
發表于 01-10 08:00
?2次下載
片機實現延時的兩種方法
來源:大魚機器人 第一篇 實現延時通常有兩種方法:一種是硬件延時,要用到定時器/計數器,這種方法可以提高CPU的工作效率,也能做到精確延時;
PCI設備兩種底層訪問方法的實現及比較分析
介紹了在VB開發環境下,對PCI設備進行底層訪問的兩種方法:一種是通過用用戶自己編寫的動態連接庫(DLL)實現,二是利用WINDRIVER提供的VB運行庫編寫直接訪問硬件接口函數,并對兩種方法
opencv實戰——機器視覺檢測和計數
由于之前網購的維生素片,有時候忘了今天有沒有吃過,就想對瓶子里的藥片計數...在學習opencv以后,希望實現對于維生素片分割計數算法。本次
OpenCV兩種不同方法實現粘連大米分割計數
評論