判断单张图片是否存在重叠部分的常见方法

2024-01-21 23:44

本文主要是介绍判断单张图片是否存在重叠部分的常见方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Python-判断单张图片中是否存在重叠部分的常见方法通常包括以下几种:

  1. 使用边缘检测和轮廓发现
    像上面提到的那样,你可以使用OpenCV库中的边缘检测(如Canny算法)和轮廓发现函数findContours,利用轮廓层级关系来判断是否有重叠。
  2. 特征匹配
    这适用于需要检测图像中相似对象重叠的情况。可以通过SIFT、SURF或ORB等特征点检测和描述算子兼已知模式匹配的方法来识别重叠部分。
  3. 模板匹配
    对于已知模板的情况,可以使用OpenCV的模板匹配函数matchTemplate。如果模板在图像中匹配多个位置,则可以推断这些区域与模板重叠。
  4. 根据像素值分析
    分析图像中每个像素与其邻居之间的关系,由此可以检测重叠的纹理或图案。(例如:使用局部二值模式Local Binary Patterns (LBPs))
  5. 机器学习和深度学习
    创建一个定制的模型来学习识别重叠部分的特征。例如,使用基于卷积神经网络(CNN)的深度学习模型,可以在图像中识别和定位重叠部分
    用边缘检测和轮廓查找来实现的简单示例
import cv2
def find_buff_1():# 加载图片image = cv2.imread('1.png')# 转换图片为灰度图gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 应用阈值化,以便更容易找到轮廓_, thresh = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY_INV)# 找到轮廓contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 遍历轮廓,检查层级关系overlap = Falseif hierarchy is None:print("没有找到轮廓")else:# hierarchy结构:[Next, Previous, First_Child, Parent]# 当轮廓具有Parent时(hierarchy[0, i, 3] != -1),它可能是重叠的for i in range(len(contours)):if hierarchy[0, i, 3] != -1:overlap = True# 这里简单地输出重叠轮廓cv2.drawContours(image, contours, i, (0, 255, 0), 3)breakif overlap:print("存在重叠的部分")cv2.imshow("Overlaps", image)cv2.waitKey(0)cv2.destroyAllWindows()else:print("不存在重叠的部分")

SIFT、SURF和ORB是用于特征点检测和描述的三种不同算法,它们可以用来在图像中找到关键点,并且为这些关键点生成一个描述符(descriptor)来捕获其周围区域的唯一性。这些算法特别适用于图像匹配、对象识别、立体视觉和导航等问题,因为它们对图像旋转、尺度变换、亮度变化等有一定的不变性(即使图像的角度或大小不同,也能识别出相同的特征点)。

下面分别介绍这三种技术:
SIFT(尺度不变特征变换)
SIFT算法由David Lowe在1999年首次提出,并在2004年完善。SIFT用于检测和描述图像中的局部特征点,并具有很高的尺度和旋转不变性。SIFT的关键步骤包括:

尺度空间极值检测:搜索所有尺度上的图像位置。通过高斯微分函数来识别潜在的具有不变性的关键点。
关键点定位:在每个候选的位置上精确定位关键点。
方向确定:基于局部图像梯度的方向,给每个关键点分配一个或多个方向。
关键点描述:在每个关键点周围的区域内测量图像的局部梯度直方图,并转化为描述符。
SURF(加速鲁棒特征)
SURF算法由Bay等人在2006年提出,被认为是SIFT的加速版本。它在很多方面与SIFT相似,但利用了近似或者整数的特征点检测方法从而加速计算过程。SURF侧重于速度和性能,并能在计算描述子时保持较高的尺度和旋转不变性。

ORB(Oriented FAST and Rotated BRIEF)
ORB算法由Rublee等人于2011年提出,是一种非常高效的特征点检测和描述算法。ORB基于FAST关键点检测器和BRIEF描述符,它进行了一些改进,以提高匹配的稳定性和对旋转的不变性。ORB首先使用FAST来查找关键点,然后用哈里斯角点测度对这些关键点进行排序以找到顶部N个点。使用图像的中心矩(intensity weighted centroid)来指定方向,然后它采用一个角度相对于方向旋转的BRIEF描述符。

由于SIFT和SURF是受专利保护的算法,所以在商业应用中可能需要获得许可才能使用。而ORB是一种免费的算法,对于需要免费且效果较好的特征检测与匹配方法而言,ORB是一个很好的选择。

这些算法可以使用OpenCV库在Python中轻松实现,以下是ORB算法的一个使用示例:

import cv2
import numpy as np# 读取图像
img = cv2.imread('path_to_image.jpg', 0)
# 初始化ORB检测器
orb = cv2.ORB_create()
# 检测关键点
keypoints = orb.detect(img, None)
# 计算描述子
keypoints, descriptors = orb.compute(img, keypoints)
# 可视化关键点
out_img = np.zeros_like(img)
out_img = cv2.drawKeypoints(img, keypoints, out_img, color=(255,0,0))
# 显示图像
cv2.imshow('ORB keypoints', out_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

OpenCV库提供了模板匹配函数 cv2.matchTemplate(),它是一个简单而有效的方法来在更大的图像中搜索和找到模板图像的位置。模板匹配通过在原始图像中滑动模板图像以作为子图像,并在每一个位置上比较子图像与模板的相似度,来工作。
这种方法对于寻找不同尺度或旋转的模板可能不是很有效,因为 matchTemplate 仅仅检查位置的匹配,但对于没有旋转和尺度变化的图像来说,它是一个非常直接的解决方案。
OpenCV提供了几种不同的比较方法,如 cv2.TM_CCOEFF, cv2.TM_CCOEFF_NORMED, cv2.TM_CCORR, cv2.TM_CCORR_NORMED, cv2.TM_SQDIFF, 和 cv2.TM_SQDIFF_NORMED。通常 cv2.TM_CCOEFF_NORMED 和 cv2.TM_CCORR_NORMED 提供归一化的分数,便于解释。

import cv2
import numpy as np# 读取原始图像和模板图像
img = cv2.imread('path_to_image.jpg')
template = cv2.imread('path_to_template.jpg')
h, w = template.shape[:2]
# 执行模板匹配操作
res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)
# 设定阈值和匹配方法
threshold = 0.8
# 仅挑选匹配程度高于阈值的点
loc = np.where(res >= threshold)
# 用矩形标注匹配到的区域
for pt in zip(*loc[::-1]):  # Switch collumns and rowscv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0,255,0), 2)
# 显示绘制了矩形标注的原始图像
cv2.imshow('Detected', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在上面的代码中,首先读取原始图像和模板图像文件,然后使用 matchTemplate 函数找到模板在原始图像中的所有匹配区域。之后,基于特定的阈值,通过 np.where 函数找到匹配度较高的点的坐标。每个点的坐标代表模板图像左上角在原始图像中的位置。然后,使用 cv2.rectangle 函数画出矩形标注,标识出匹配到的区域。

通常,如果在图像中找到了多个匹配区域,可能表明图像中存在多个相似或相同的模板,这有时候也可以理解为一种重叠,尤其是当模板小于或接近待检测的物体大小时。不过,要注意 matchTemplate 不是专门设计来检测重叠的方法。如果需要处理旋转或尺度变化,可能需要考虑更复杂的特征点匹配算法

局部二值模式(Local Binary Patterns,简称LBPs)是一种简单而有效的纹理描述子。它在各种条件下表现出了良好的稳定性和鲁棒性,特别适用于纹理分类。LBPs可以提取图像局部区域内的纹理信息,通过比较每个像素与其周围邻居的强度来生成一个二进制数。

基本的LBP算子定义如下:
选取图像中的一个像素作为中心像素。
将中心像素的邻域(通常是3x3、5x5等)的每个像素的强度值与中心像素的值进行比较。
如果周围的像素值大于中心像素值,则该位置记为1,否则记为0。
这样会得到每个像素的一个二进制数(二进制模式),将这个二进制数转换为十进制作为该中心像素的新值。
对图像中的所有像素重复上述过程,最后得到的新图像就是LBP特征图。
LBP特征图可以用于纹理识别,也可以用于查找图像中的重复模式或纹理,在某些情况下可能隐含着重叠区域。

注意,直接使用LBP可能不能确定图像中是否存在重叠部分。为了使用LBP分析重叠,您可能需要结合其他图像处理步骤,例如分割图像中可能重叠的区域,然后在这些区域使用LBP来比较它们的纹理模式。如果两个区域具有高度相似的LBPs,则它们可能包含重叠的纹理。

import cv2
import numpy as np
from skimage import feature# 读取灰度图像
image = cv2.imread('path_to_image.jpg', cv2.IMREAD_GRAYSCALE)# 使用skimage库中的LBP函数
radius = 1  # LBP中用到的圆的半径
n_points = 8 * radius  # 采样点的数量
lbp = feature.local_binary_pattern(image, n_points, radius, method="uniform")
# 现在,lbp变量包含了图像的LBP特征图
# 你可以做更多的处理,比如计算LBP图像的直方图:
lbp_hist, _ = np.histogram(lbp, bins=np.arange(257), range=(0, 256))
lbp_hist = lbp_hist.astype("float")
lbp_hist /= (lbp_hist.sum() + 1e-7)  # 归一化直方图
# 这个直方图现在可以用于纹理分类或被用作特征向量进一步的图像分析。
# 可视化LBP图像
cv2.imshow('LBP Image', lbp.astype('float32'))
cv2.waitKey(0)
cv2.destroyAllWindows()

这里,使用feature.local_binary_pattern函数从skimage库中计算LBP图,然后计算它的直方图。这个直方图可以作为一种特征向量在图像间比较纹理。
要使用这个直方图进行重叠检测,你可以比较多个区域的LBP直方图,并根据相似度来判断是否存在重叠。这通常需要额外的逻辑来定义何种程度的相似度阈值被认为是重叠.

这篇关于判断单张图片是否存在重叠部分的常见方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/631200

相关文章

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

macOS无效Launchpad图标轻松删除的4 种实用方法

《macOS无效Launchpad图标轻松删除的4种实用方法》mac中不在appstore上下载的应用经常在删除后它的图标还残留在launchpad中,并且长按图标也不会出现删除符号,下面解决这个问... 在 MACOS 上,Launchpad(也就是「启动台」)是一个便捷的 App 启动工具。但有时候,应

SpringBoot日志配置SLF4J和Logback的方法实现

《SpringBoot日志配置SLF4J和Logback的方法实现》日志记录是不可或缺的一部分,本文主要介绍了SpringBoot日志配置SLF4J和Logback的方法实现,文中通过示例代码介绍的非... 目录一、前言二、案例一:初识日志三、案例二:使用Lombok输出日志四、案例三:配置Logback一

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

mysql出现ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost‘ (10061)的解决方法

《mysql出现ERROR2003(HY000):Can‘tconnecttoMySQLserveron‘localhost‘(10061)的解决方法》本文主要介绍了mysql出现... 目录前言:第一步:第二步:第三步:总结:前言:当你想通过命令窗口想打开mysql时候发现提http://www.cpp