背景介紹
測(cè)試圖如下,圖中有個(gè)別米粒相互粘連,本文主要演示如何使用OpenCV用兩種不同方法將其分割并計(jì)數(shù)。
方法一:基于分水嶺算法
基于分水嶺算法分割步驟如下:
【1】高斯濾波 + 二值化 +開運(yùn)算
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)# 轉(zhuǎn)成8位整型 cv2.imshow('Sure foreground', sure_fg)
【3】標(biāo)記位置區(qū)域
# 未知區(qū)域標(biāo)記為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】輪廓查找和標(biāo)記
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】高斯濾波 + 二值化 +開運(yùn)算
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)#默認(rèn)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最大的兩個(gè)凸包缺陷點(diǎn)連起來(lái),將二值圖中對(duì)應(yīng)的粘連區(qū)域分割開,紅色圓標(biāo)注為分割開的部分
if len(pt_list) > 0: cv2.line(binary,pt_list[0],pt_list[1],0,2) cv2.imshow('binary2',binary)
【4】重新查找輪廓并標(biāo)記結(jié)果
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
審核編輯:劉清
-
高斯濾波
+關(guān)注
關(guān)注
0文章
18瀏覽量
8085 -
OpenCV
+關(guān)注
關(guān)注
31文章
635瀏覽量
41461
原文標(biāo)題:實(shí)戰(zhàn) | OpenCV兩種不同方法實(shí)現(xiàn)粘連大米分割計(jì)數(shù)(步驟 + 代碼)
文章出處:【微信號(hào):vision263com,微信公眾號(hào):新機(jī)器視覺】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論