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

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

相关文章

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

浅谈主机加固,六种有效的主机加固方法

在数字化时代,数据的价值不言而喻,但随之而来的安全威胁也日益严峻。从勒索病毒到内部泄露,企业的数据安全面临着前所未有的挑战。为了应对这些挑战,一种全新的主机加固解决方案应运而生。 MCK主机加固解决方案,采用先进的安全容器中间件技术,构建起一套内核级的纵深立体防护体系。这一体系突破了传统安全防护的局限,即使在管理员权限被恶意利用的情况下,也能确保服务器的安全稳定运行。 普适主机加固措施:

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

zoj 1721 判断2条线段(完全)相交

给出起点,终点,与一些障碍线段。 求起点到终点的最短路。 枚举2点的距离,然后最短路。 2点可达条件:没有线段与这2点所构成的线段(完全)相交。 const double eps = 1e-8 ;double add(double x , double y){if(fabs(x+y) < eps*(fabs(x) + fabs(y))) return 0 ;return x + y ;

POJ1269 判断2条直线的位置关系

题目大意:给两个点能够确定一条直线,题目给出两条直线(由4个点确定),要求判断出这两条直线的关系:平行,同线,相交。如果相交还要求出交点坐标。 解题思路: 先判断两条直线p1p2, q1q2是否共线, 如果不是,再判断 直线 是否平行, 如果还不是, 则两直线相交。  判断共线:  p1p2q1 共线 且 p1p2q2 共线 ,共线用叉乘为 0  来判断,  判断 平行:  p1p