社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

基于Python的OpenCV轮廓检测聚类

计算机视觉life • 2 年前 • 290 次点击  

点击上方“计算机视觉life”,选择“星标”

快速获得最新干货

本文转载自小白学视觉,文章仅用于学术分享。


简介


OpenCV的“findContours”功能经常被计算机视觉工程师用来检测物体。OpenCV的存在,使得我们只需要编写几行代码就可以检测轮廓(对象)。然而,OpenCV检测到的轮廓通常是分散的。例如,一个功能丰富的图像可能有数百到数千个轮廓,但这并不意味着图像中有那么多对象。一些属于同一对象的轮廓是单独检测的,因此我们感兴趣的是对它们进行分组,使一个轮廓对应一个对象。


实现思路


当我在项目中遇到这个问题时,我花了很多时间尝试使用不同的参数或不同的OpenCV函数来检测轮廓,但没有一个有效。然后,我做了更多的研究,在OpenCV的论坛上找到了一篇帖子,它提到了凝聚聚类。但是,没有给出源代码。我还发现sklearn支持聚合聚类,但我没有使用它,原因有两个:

  1. 这个功能对我来说似乎很复杂。我不知道如何输入正确的参数,我怀疑轮廓检测的数据类型是否适合该函数。
  2. 我需要使用python 2.7、OpenCV 3.3.1和Numpy 1.11.3。它们与sklearn的版本(0.20+)不兼容,后者支持聚类。



源代码


为了分享我编写的函数,我在Github中对其进行了开源,并将其作为要点发布在下面。以下版本适用于Python3,若需要要在Python2.7中使用它,只需将“range”更改为“xrange”。

#!/usr/bin/env python3
import osimport cv2import numpy
def calculate_contour_distance(contour1, contour2): x1, y1, w1, h1 = cv2.boundingRect(contour1) c_x1 = x1 + w1/2 c_y1 = y1 + h1/2
x2, y2, w2, h2 = cv2.boundingRect(contour2) c_x2 = x2 + w2/2 c_y2 = y2 + h2/2
return max(abs(c_x1 - c_x2) - (w1 + w2)/2, abs(c_y1 - c_y2) - (h1 + h2)/2)
def merge_contours(contour1, contour2): return numpy.concatenate((contour1, contour2), axis=0)
def agglomerative_cluster(contours, threshold_distance=40.0): current_contours = contours while len(current_contours) > 1: min_distance = None min_coordinate = None
for x in range(len(current_contours)-1): for y in range(x+1, len(current_contours)): distance = calculate_contour_distance(current_contours[x], current_contours[y]) if min_distance is None: min_distance = distance min_coordinate = (x, y) elif distance < min_distance: min_distance = distance min_coordinate = (x, y)
if min_distance < threshold_distance: index1, index2 = min_coordinate current_contours[index1] = merge_contours(current_contours[index1], current_contours[index2]) del current_contours[index2] else: break
return current_contours

注意:

  • “calculate_contour_distance”函数获取轮廓的边界框,并计算两个矩形之间的距离。

  • “merge_contours”函数,我们只需使用'numpy.concatenate'即可,因为每个轮廓只是一个点的numpy数组。

  • 使用聚类算法,我们不需要事先知道有多少个聚类。相反,可以向函数提供阈值距离,例如40个像素,因此如果所有轮廓中最近的距离大于阈值,则函数将停止处理。


结果


要可视化集群效果,请参见下面的两幅图像。第一幅图像显示最初检测到12个轮廓,聚类后只剩下4个轮廓,如第二幅图像所示。这两个小对象是由于噪声造成的,它们没有合并,因为与阈值距离相比,它们离太远。




GITHUB代码链接:

https://github.com/CullenSUN/fish_vision/blob/master/obstacle_detector_node/src/opencv_utils.py


独家重磅课程!

1、详解Cartographer:谷歌开源的激光SLAM算法Cartographer为什么这么牛X?

2、深度学习三维重建 详解深度学习三维重建网络:MVSNet、PatchMatchNet、JDACS-MS

3、三维视觉基础 详解视觉深度估计算法(单/双目/RGB-D+特征匹配+极线矫正+代码实战)

4、视觉SLAM必备基础 详解视觉SLAM核心:地图初始化、实时跟踪、局部建图、回环检测、BA优化,工程技巧

5、 VINS:Mono+Fusion SLAM面试官:看你简历上写精通VINS,麻烦现场手推一下预积分!

6、VIO进阶:ORB-SLAM3(单/双目/RGBD+鱼眼+IMU紧耦合+多地图+闭环)独家70+讲全部上线!

7、图像三维重建课程:视觉几何三维重建教程(第2期):稠密重建,曲面重建,点云融合,纹理贴图

8、重磅来袭!基于LiDAR的多传感器融合SLAM 系列教程:LOAM、LeGO-LOAM、LIO-SAM

9、系统全面的相机标定课程:单目/鱼眼/双目/阵列 相机标定:原理与实战



全国最棒的SLAM、三维视觉学习社区↓


技术交流微信群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN算法竞赛等微信群,请添加微信号 chichui502 或扫描下方加群,备注:”名字/昵称+学校/公司+研究方向“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

投稿、合作也欢迎联系:simiter@126.com


扫描关注视频号,看最新技术落地及开源方案视频秀 ↓



—   版权声明  —

本公众号原创内容版权属计算机视觉life所有;从公开渠道收集、整理及授权转载的非原创文字、图片和音视频资料,版权属原作者。如果侵权,请联系我们,会及时删除。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/126004
 
290 次点击