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

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

相关文章

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

Python中使用defaultdict和Counter的方法

《Python中使用defaultdict和Counter的方法》本文深入探讨了Python中的两个强大工具——defaultdict和Counter,并详细介绍了它们的工作原理、应用场景以及在实际编... 目录引言defaultdict的深入应用什么是defaultdictdefaultdict的工作原理

使用Python进行文件读写操作的基本方法

《使用Python进行文件读写操作的基本方法》今天的内容来介绍Python中进行文件读写操作的方法,这在学习Python时是必不可少的技术点,希望可以帮助到正在学习python的小伙伴,以下是Pyth... 目录一、文件读取:二、文件写入:三、文件追加:四、文件读写的二进制模式:五、使用 json 模块读写

Spring常见错误之Web嵌套对象校验失效解决办法

《Spring常见错误之Web嵌套对象校验失效解决办法》:本文主要介绍Spring常见错误之Web嵌套对象校验失效解决的相关资料,通过在Phone对象上添加@Valid注解,问题得以解决,需要的朋... 目录问题复现案例解析问题修正总结  问题复现当开发一个学籍管理系统时,我们会提供了一个 API 接口去

C#中图片如何自适应pictureBox大小

《C#中图片如何自适应pictureBox大小》文章描述了如何在C#中实现图片自适应pictureBox大小,并展示修改前后的效果,修改步骤包括两步,作者分享了个人经验,希望对大家有所帮助... 目录C#图片自适应pictureBox大小编程修改步骤总结C#图片自适应pictureBox大小上图中“z轴

Oracle数据库使用 listagg去重删除重复数据的方法汇总

《Oracle数据库使用listagg去重删除重复数据的方法汇总》文章介绍了在Oracle数据库中使用LISTAGG和XMLAGG函数进行字符串聚合并去重的方法,包括去重聚合、使用XML解析和CLO... 目录案例表第一种:使用wm_concat() + distinct去重聚合第二种:使用listagg,

Java后端接口中提取请求头中的Cookie和Token的方法

《Java后端接口中提取请求头中的Cookie和Token的方法》在现代Web开发中,HTTP请求头(Header)是客户端与服务器之间传递信息的重要方式之一,本文将详细介绍如何在Java后端(以Sp... 目录引言1. 背景1.1 什么是 HTTP 请求头?1.2 为什么需要提取请求头?2. 使用 Spr

Java如何通过反射机制获取数据类对象的属性及方法

《Java如何通过反射机制获取数据类对象的属性及方法》文章介绍了如何使用Java反射机制获取类对象的所有属性及其对应的get、set方法,以及如何通过反射机制实现类对象的实例化,感兴趣的朋友跟随小编一... 目录一、通过反射机制获取类对象的所有属性以及相应的get、set方法1.遍历类对象的所有属性2.获取

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

使用Python将长图片分割为若干张小图片

《使用Python将长图片分割为若干张小图片》这篇文章主要为大家详细介绍了如何使用Python将长图片分割为若干张小图片,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. python需求的任务2. Python代码的实现3. 代码修改的位置4. 运行结果1. Python需求