百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

基于Python的OpenCV轮廓检测聚类

csdh11 2025-05-25 11:44 7 浏览

简介

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 os
import cv2
import 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个轮廓,如第二幅图像所示。这两个小对象是由于噪声造成的,它们没有合并,因为与阈值距离相比,它们离太远。

相关推荐

IntelliJ IDEA 部署 Web 项目,终于搞懂了

IDEA中最重要的各种设置项,就是这个ProjectStructre了,关乎你的项目运行,缺胳膊少腿都不行。最近公司正好也是用之前自己比较熟悉的IDEA而不是Eclipse,为了更深入理解和使...

[应用篇]第四篇 JSTL之C标签介绍.md

粗体为必须掌握部分表达式控制标签:out、set、remove、catch流程控制标签:if、choose、when、otherwise...

HikariCP为啥这么火?SpringBoot选它的原因?

简介HikariCP是用于创建和管理连接,利用“池”的方式复用连接减少资源开销,和其他数据源一样,也具有连接数控制、连接可靠性测试、连接泄露控制、缓存语句等功能,另外,和druid一样,Hika...

Jeecg-P3 1.0版本发布,JAVA插件开发框架

Jeecg-P31.0版本发布,插件开发框架特点:业务组件以JAR方式提供,插件模式、松耦合、可插拔、支持独立部署,也可以无缝集成Jeecg平台中。【架构说明】1.Jeecg-P3采用Sprin...

来来来!一文告诉你Eclipse的正确安装使用姿势,你都清楚吗?

前言本学习笔记是有关如何设置Eclipse的详细说明。即使你天天在使用它,但是,相信我,或许你并不足够了解它。安装Java运行时环境Eclipse是Java应用程序,因此设置Eclipse的第一步是安...

SpringBoot项目jar、war包启动解析

一、jar包和war包的区别1.1war包war包是JavaWeb应用程序的一种打包方式符合Servlet标准,它是WebArchive的缩写,主要用于存储Web应用程序相关的文件,包括Java...

「Tomcat优化篇」如何让你的Tomcat性能更加优越 一遍就懂

Tomcat优化篇一、Tomcat自身配置1.Tomcat管理页面...

深入理解JSP

第一章JSP1、概述1.1JSP引入在前面的登录案例中,登录失败后为了能够响应登录的错误信息。我特意创建了一个LoginErrorServlet用来动态地拼接错误信息。...

Struts2.3.32升级到2.5.26详细步骤(无敌版)

Struts2真是三天两头爆出漏洞来,特别是一爆出漏洞就建议升级到最新版,也是无语的,并且最新版相比老板还相差挺大的,这部这次需要从Struts2.3.32一下子就必须升级到最新版,这可让人头大,谷歌...

java中的jar包,war包详解

做java开发的,对jar包和war包肯定接触的不少。我们有必要对他们做一个深入的了解。现在我们整理一下。jar包的介绍JAR(JavaArchive)是与平台无关的文件格式,它允许将许多文件组合成...

Java文件上传与下载

1文件上传1.1文件上传入门1.1.1实现文件上传条件1)表单的提交方式必须是...

还在用JSP中的脚本程序吗?去掉吧,我教你快速掌握EL及JSTL

jsp页面可以使用脚本程序(java代码)来实现页面逻辑,但是维护比较困难。可以使用EL来访问和处理应用程序的数据。JSTL来替换页面显示逻辑的java代码。非常简单!保证你会用后就不会再用jsp脚本...

Servlet 容器

Servlet容器主要是JavaWeb应用提供运行时环境,所以也可以称之为JavaWeb应用容器,或者Servlet/JSP容器。Servlet容器主要负责管理Servlet、JSP的生命周期以及它们...

Java-Maven详解

一、什么是Maven?ApacheMaven是一个软件...

阿里面试题:Tomcat为什么要自定义类加载器?价值20K的面试题!

你是否曾好奇,为何Tomcat作为JavaWeb服务器的佼佼者,偏偏不走寻常路,要自定义一套类加载器机制?这背后,不仅隐藏着解决Java类加载复杂性的智慧,更蕴含着提升应用隔离性、安全性与灵活性的深...