背景介绍
测试图如下,图中有个别米粒相互粘连,本文主要演示如何使用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文章
12浏览量
8040 -
OpenCV
+关注
关注
29文章
611浏览量
40786
原文标题:实战 | OpenCV两种不同方法实现粘连大米分割计数(步骤 + 代码)
文章出处:【微信号:vision263com,微信公众号:新机器视觉】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
比较两种实现方法计算200 万次开普勒方程所用时间怎么构建
均值和报警次数。5. 使用For 循环、Case 结构及顺序结构构建VI。要求分别使用公式节点和LabVIEW 算术函 数实现开普勒方程 y=x-esin x , 0≤e≤1,使用利用顺序结构和定时选板下的时间计数 器.vi 比较两种
发表于 04-02 11:14
两种verilog语言写法的实现问题!求解答~
在看verilog代码时,看到这样两种表示方法:一种是:“ wirea;assigna=b;”一种是:“wirea=b;”请教各位大神这两种
发表于 01-29 14:33
求助:本人想实现一个按键来控制两种不同的方波信号输出,两种方波之间间隔1秒的时间(具体如下)
P1.1口输出一种方波,1S后输出另外一种方波(两种方波大小差别较大就行)当P1.3口检测到低电平是,单片机P1.1无输出。我试过几种方式都不能成功,包括采用定时器和计数器,中断都试过
发表于 11-22 22:59
两种阻抗匹配方法讨论
应用阻抗匹配器使负载与传输线特性阻抗相匹配,如图 2-12 所示。由于信源端一般用隔离器或去耦衰减器以实现信源端匹配, 因此我们着重讨论负载匹配的方法.阻抗匹配方法从频率上划分为窄带匹配和宽带匹配,从
发表于 06-03 06:51
一种先分割后分类的两阶段同步端到端缺陷检测方法
作者:SFXiang首发:AI算法修炼营本文是一种端到端的先分割后分类的表面缺陷检测方法。主要的创新点在于如何将两类任务更好地进行同步学习,本文首先平衡
发表于 07-24 11:01
【原创分享】单片机延时的两种实现方法
比较多,但是相对而言汇编更精准。从实现方式来看,有软件方式和硬件方式,那么对于C语言延时的方法哪种更精准呢?自然是定时器计数器的方式了,为什么呢?一起来看看吧。1、软件延时-循环实现在
发表于 10-08 15:32
1.3 两种运行 Python 程序方法
1.3 两种运行 Python 程序方法前两节我们安装好了 CPython 解释器,有了解释器,就可以运行 Python 程序了。Python 程序的执行分为两种:使用Python C
发表于 02-16 18:31
opencv实战——机器视觉检测和计数
由于之前网购的维生素片,有时候忘了今天有没有吃过,就想对瓶子里的药片计数...在学习opencv以后,希望实现对于维生素片分割计数算法。本次
评论