0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

OpenCV两种不同方法实现粘连大米分割计数

新机器视觉 来源:OpenCV与AI深度学习 2024-01-22 14:55 次阅读

背景介绍

测试图如下,图中有个别米粒相互粘连,本文主要演示如何使用OpenCV用两种不同方法将其分割并计数。

a3382ca8-b76b-11ee-8b88-92fbcf53809c.png

方法一:基于分水岭算法

基于分水岭算法分割步骤如下:

【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)

a35c9bba-b76b-11ee-8b88-92fbcf53809c.png

【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)

a36cca8a-b76b-11ee-8b88-92fbcf53809c.png

a37e309a-b76b-11ee-8b88-92fbcf53809c.png

【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)

a396b1f6-b76b-11ee-8b88-92fbcf53809c.png

【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)

a3a984a2-b76b-11ee-8b88-92fbcf53809c.png

方法二:轮廓凸包缺陷方法

基于轮廓凸包缺陷分割步骤如下:

【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)

a35c9bba-b76b-11ee-8b88-92fbcf53809c.png

【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

a3d70634-b76b-11ee-8b88-92fbcf53809c.png

【3】将距离d最大的两个凸包缺陷点连起来,将二值图中对应的粘连区域分割开,红色圆标注为分割开的部分

    if len(pt_list) > 0:
cv2.line(binary,pt_list[0],pt_list[1],0,2)
cv2.imshow('binary2',binary)
a3eca9b2-b76b-11ee-8b88-92fbcf53809c.png

a3f9a180-b76b-11ee-8b88-92fbcf53809c.png

【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

a40c807a-b76b-11ee-8b88-92fbcf53809c.png






审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 高斯滤波
    +关注

    关注

    0

    文章

    18

    浏览量

    8069
  • OpenCV
    +关注

    关注

    31

    文章

    635

    浏览量

    41357

原文标题:实战 | OpenCV两种不同方法实现粘连大米分割计数(步骤 + 代码)

文章出处:【微信号:vision263com,微信公众号:新机器视觉】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    测量开关电源转换效率的两种同方法

    本文将向大家介绍测量开关电源转换效率的两种同方法
    发表于 08-09 16:45 4533次阅读
    测量开关电源转换效率的<b class='flag-5'>两种</b>不<b class='flag-5'>同方法</b>

    两种LED驱动模式的功能及使用方法

    中颖MCU普通LED模块(非恒流)提供了两种LED驱动模式:亮灭模式、调光模式。两种模式的功能及使用方法简介如下。
    发表于 08-26 11:18 3583次阅读

    新的粘连字符图像分割方法

    新的粘连字符图像分割方法针对监控画面采样图像中数字的自动识别问题,提出一新的粘连字符图像
    发表于 09-19 09:19

    两种verilog语言写法的实现问题!求解答~

    在看verilog代码时,看到这样两种表示方法:一是:“ wirea;assigna=b;”一是:“wirea=b;”请教各位大神这两种
    发表于 01-29 14:33

    二值化图像后分割粘连的区域如何分割

    `二值化图像粘连后如果是圆形的物体可以使用分水岭或找圆进行分割。如果是其它形状如椭圆或图中形状如何分割请教高手帮忙`
    发表于 03-31 22:46

    两种使用C#实现ADSL自动拨号的方法

    在网络编程中,有时候会需要重新拨号建立网络连接(如Ad点击软件通过重新拨号形成有效点击) ,下面介绍两种程序中拨号的方法.
    发表于 07-12 06:33

    基于LabVIEW的Modbus协议两种校验码的实现方法

    基于LabVIEW的Modbus协议两种校验码的实现方法 介绍基于LabVIEW的Modbus协议两种校验码的实现
    发表于 10-13 00:08 4409次阅读
    基于LabVIEW的Modbus协议<b class='flag-5'>两种</b>校验码的<b class='flag-5'>实现</b><b class='flag-5'>方法</b>

    基于ADI的UHF RFID读卡器射频前端的两种实现方法解析

    本文介绍基于ADI公司的信号链的UHF RFID读卡器射频前端的两种实现方法
    发表于 10-25 16:00 3246次阅读
    基于ADI的UHF RFID读卡器射频前端的<b class='flag-5'>两种</b><b class='flag-5'>实现</b><b class='flag-5'>方法</b>解析

    单片机系统实现延时的两种方法解析

    实现延时通常有两种方法:一是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一
    发表于 01-24 17:06 1.4w次阅读
    单片机系统<b class='flag-5'>实现</b>延时的<b class='flag-5'>两种方法</b>解析

    Multibool的两种实现方法详细资料介绍

    介绍了Multibool的两种实现方法。通过Xilinx Spartan-6 FPGA的Multiboot特性,允许用户一次将多个配置文件下载入Flash中,根据不同时刻的需求,在不掉电重启的情况下,从中选择一个来重配置FPGA
    发表于 01-10 08:00 2次下载

    两种线路板分割的方式及多层线路板具体分割方法

    下面就为大家介绍两种线路板分割的方式以及多层线路板具体分割方法
    发表于 07-25 11:06 6060次阅读

    片机实现延时的两种方法

    来源:大鱼机器人 第一篇 实现延时通常有两种方法:一是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;
    的头像 发表于 09-11 14:29 3070次阅读

    PCI设备两种底层访问方法实现及比较分析

    介绍了在VB开发环境下,对PCI设备进行底层访问的两种方法:一是通过用用户自己编写的动态连接库(DLL)实现,二是利用WINDRIVER提供的VB运行库编写直接访问硬件接口函数,并对两种方法
    的头像 发表于 10-04 17:25 3314次阅读
    PCI设备<b class='flag-5'>两种</b>底层访问<b class='flag-5'>方法</b>的<b class='flag-5'>实现</b>及比较分析

    单片机实现延时两种方法

    实现延时通常有两种方法:一是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一
    发表于 11-04 15:36 12次下载
    单片机<b class='flag-5'>实现</b>延时<b class='flag-5'>两种方法</b>

    opencv实战——机器视觉检测和计数

    由于之前网购的维生素片,有时候忘了今天有没有吃过,就想对瓶子里的药片计数...在学习opencv以后,希望实现对于维生素片分割计数算法。本次
    的头像 发表于 03-03 11:54 1992次阅读