如何使用 OpenCV 检测图像帧中的对象?

2024-05-05

我正在使用 Raspberry Pi 开发一个漫游器,它将清扫房间并捡起掉落在地上的物体。为了检测物体,我使用了在流动站操作开始时拍摄的参考图像,以及每 10 秒单击一次的图像(新图像)。为了确定图像帧是否发生变化,我在参考图像和新图像之间进行了图像减法。如果发现任何差异,它会在其周围绘制轮廓,如果轮廓面积大于某个阈值(警告步骤),则得出存在对象的结论。

我正在使用以下代码 -

import numpy as np
import cv2,time

img=cv2.imread("object1.jpg")
img1=cv2.imread("object2.jpg")
sub=cv2.subtract(img,img1)

gray=cv2.cvtColor(sub,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(3,3),0)
_, contours, _= cv2.findContours(blur,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
c=max(contours,key=cv2.contourArea)
print(cv2.contourArea(c))

if cv2.contourArea>20000:
   print("Object detected !")

上面的代码仅使用 2 个图像来计算它们的差异并确定是否存在对象。请注意,我没有在这里发布我将在我的项目中使用的原始代码。

现在,上面的代码适用于非常受控的情况,例如,当图像背景非常恒定或其中不存在阴影时。但考虑到流动站将在房间内移动,即使框架中没有真实物体,照明变化也有可能触发错误的物体检测。这种差异可能是由于阴影效果的错误轮廓而引发的。

我想知道是否有其他方法可以在不进行前景/背景图像减法的情况下实现此对象检测。我还考虑过使用超声波传感器来检测物体的存在,但这不是一个非常可靠的选择。我更喜欢基于图像处理的解决方案。

谢谢 。

=================================================== =======================

EDIT 1 -

所以,我决定稍微改变一下算法。我对前景和背景图像都进行了阈值处理,然后在二进制图像之间执行absdiff,以获得任何帧变化(对象)。 代码如下——

import numpy as np
import cv2,time

img1=cv2.imread("back.jpeg")
blur1 = cv2.GaussianBlur(img1,(5,5),0)
gray1=cv2.cvtColor(blur1,cv2.COLOR_BGR2GRAY)
ret,thresh1 = cv2.threshold(gray1,65,255,cv2.THRESH_BINARY_INV)

img2=cv2.imread("front.jpeg")
blur2 = cv2.GaussianBlur(img2,(5,5),0)
gray2=cv2.cvtColor(blur2,cv2.COLOR_BGR2GRAY)
ret,thresh2 = cv2.threshold(gray2,65,255,cv2.THRESH_BINARY_INV)

diff=cv2.absdiff(thresh2,thresh1)
diff=cv2.bitwise_xor(diff,thresh1)

kernel = np.ones((2,2),np.uint8)
diff=cv2.erode(diff,kernel,iterations = 1)
diff=cv2.dilate(diff,kernel,iterations = 8)

_, contours, _= cv2.findContours(diff,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
c=max(contours,key=cv2.contourArea)
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(diff,(x,y),(x+w,y+h),(125,125,125),2)


cv2.imshow("thresh",diff)
cv2.waitKey(0)

“absdiff”之后是 Erosion 和 Dilation 。之后,我找到最大的轮廓并确定是否存在物体。算法中使用的图像如下 -

  1. 背景图 -背景图 https://i.stack.imgur.com/3uRGM.jpg

  2. 前景图像 -前景图像 https://i.stack.imgur.com/fC8xG.jpg

  3. 前景阈值 -前景阈值图像 https://i.stack.imgur.com/OmW5k.png

  4. 背景阈值 -背景阈值图像 https://i.stack.imgur.com/ogQ3w.png

  5. 差异图像 -具有轮廓及其边界的最终图像。 https://i.stack.imgur.com/iYA9r.png

正如您所看到的,检测工作正常。我几乎没有用来测试算法的其他前景图像。他们给出了令人满意的结果。我想知道是否有其他方法可以以更高的效率达到相同的结果。

PS-所有前景图像都是在闪光灯打开的情况下拍摄的。我尝试过关闭闪光灯,但图像中似乎存在很多噪点。

=================================================== ===========

EDIT 2-

使用其他图片的算法的性能 -

注意:- 背景图像保持不变。

  1. 对象 1 -前景图像 1 https://i.stack.imgur.com/pzupl.jpg
  2. 对象 1 检测 -前景图像 1 结果 https://i.stack.imgur.com/3KMxm.png

我怀疑这个问题是否像您在问题中描述的那么简单,当我们进入现实世界场景时,它会变得非常复杂。

但无论如何,假设你的小物体只出现在房间里,那么你可以通过识别来识别它们连接的组件在捕获的二值图像中,并根据它们的相对像素大小选择它们。

下面是相同的 Python 实现:

img = cv2.imread('D:/Image/objects.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# binarize the image
ret, bw = cv2.threshold(gray, 128, 255, 
cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

# find connected components
connectivity = 4
nb_components, output, stats, centroids = 
cv2.connectedComponentsWithStats(bw, connectivity, cv2.CV_32S)
sizes = stats[1:, -1]; nb_components = nb_components - 1
min_size = 250 #threshhold value for objects in scene
img2 = np.zeros((img.shape), np.uint8)
for i in range(0, nb_components+1):
    # use if sizes[i] >= min_size: to identify your objects
    color = np.random.randint(255,size=3)
    # draw the bounding rectangele around each object
    cv2.rectangle(img2, (stats[i][0],stats[i][1]),(stats[i][0]+stats[i][2],stats[i][1]+stats[i][3]), (0,255,0), 2)
    img2[output == i + 1] = color

包含对象的图像:

使用连接组件标签检测到的对象:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 OpenCV 检测图像帧中的对象? 的相关文章

随机推荐

  • JVM 是否会内联对象的实例变量和方法?

    假设我有一个非常紧密的内部循环 每次迭代都会访问和改变一个簿记对象 该对象存储有关算法的一些简单数据 并具有用于操作它的简单逻辑 簿记对象是私有的和最终的 并且它的所有方法都是私有的 最终的和 inline 下面是一个示例 Scala 语法
  • 使用java服务中的Zxing库从单个图像文件中读取多个条形码

    您好 我已经创建了一个java服务 用于从此处的图像中读取条形码 我使用Zxing库来解码此处的文本 挑战是 如果一个带有单个条形码的文件工作正常 如果有多个条形码 它会产生不相关的结果 我在下面给出了我的代码 pom xml
  • dataframe KeyError,尽管它存在

    鉴于数据 rows x 1 y 2 z 3 x 2 y 2 z 3 如果我尝试构建这样的数据框 frame pd DataFrame from records rows index x 效果很好 然而 这 frame pd DataFram
  • 如何在 Selenium 中定位具有特定文本的跨度? (使用Java)

    我在使用 java 查找 Selenium 中的 span 元素时遇到问题 HTML 看起来像 div class settings padding span Settings span div 我尝试了以下方法但没有成功 By xpath
  • 将 $lookup 结果合并到现有数组

    我是 mongo 新手 我需要你的帮助 我有收藏学习计划 这是示例文档 id dGFY garranti typ sk garant en Chairman of study board id 1025769 typ sk predseda
  • Bootstrap 3 网格,一行中有多少列“真的”重要吗?

    我有一个表单布局 上面有 Bootstrap 3 表单组 我希望这些表单组在 我显然让它工作得很好 但是在这里阅读了一些内容后 我所做的似乎违反了假设的规则 即一行中的每一列加起来必须等于 12 但是我能找到的每个教程和文档总是使用诸如 应
  • 尝试将过滤器添加到 Grizzly+Jersey 应用程序时出现问题

    我有这个服务器初始化类 package magic app main import org glassfish grizzly http server HttpServer import org glassfish jersey grizz
  • 在 Objective-C 中从异步块增加变量

    我在 Objective C 中开发的服务遇到了一些难题 该服务的目的是解析核心数据实体列表并为每个对象下载相应的图像文件 该服务的原始设计因太多同时下载请求而阻塞了我的网络服务器 为了解决这个问题 我将负责执行下载请求的代码移至递归方法中
  • 按组保留行,直到列中值第一次出现为止。不允许存在值的组

    我有一个像这样的数据框 gt df id type 1 1 a 2 1 a 3 1 b 4 1 a 5 1 b 6 2 a 7 2 a 8 2 b 9 3 a 10 3 a 我想保留每个组 id 的所有行 直到类型列中第一次出现值 b 为止
  • 如何防止双斜杠被编码?

    我正在发出类似于以下内容的 get 请求 https endpoint com path to what want param value https endpoint com path to what want param value 我
  • Windows Phone 7 浏览器 - 单击链接时关闭灰色阴影

    使用 Windows Phone 7 浏览器 当用户单击链接时 该链接会显示一个灰色矩形阴影大约 0 5 秒 一般来说 这很好 但是 如果您有动态页面行为 例如 单击链接会更新 DOM 以便该链接不再可见 则在链接本身消失后 不透明的灰色矩
  • JavaScript:字符串连接性能低下? Array.join('')?

    我读过如果我有一个for循环 我不应该使用字符串连接 因为它很慢 例如 for i 0 i lt 10000000 i str a 相反 我应该使用Array join 因为它更快 var tmp for i 0 i lt 10000000
  • 在 Visual Studio 2010 DBML 设计器 (MS SQL/ASP.NET MVC) 中默认设置 UpdateCheck.Never 模式

    在我的网络应用程序中 我做了很多更新 因此 除主键之外的所有列唯一可接受的 UpdateCheck 模式是 NEVER 但不幸的是 DBML 设计器自动设置 ALWAYS 模式 因此 我必须手动更改数十列 并且当我必须更新 DBML 文件时
  • GIT Rebase 对多个 0.5GB 二进制文件致命

    这个问题本质上是重新开rebase 期间 git 崩溃 https stackoverflow com q 7692944 1286639从来没有答案 我正在尝试从我的 secc 分支进行变基 git rebase main First r
  • int 到 long 赋值

    我一直在尝试这个 int 和 long 转换 我尝试分配一个int变量为along多变的 代码如下 public static void main String args int i 1024 long j i long k i i i i
  • 如何使用 cURL(或任何命令行工具)通过 OAuth 身份验证将 HTTP Post 发送到 Twitter?

    我希望使用命令行应用程序 例如cURL http en wikipedia org wiki CURL cURL 在我的测试 Twitter 帐户上发布一些测试帖子 我也希望通过 OAuth 身份验证来做到这一点 我怎样才能做到这一点 假设
  • Azure 存储上的连接池

    我开始使用 Azure 存储将文件保存到应用程序上的 blob 由于我的应用程序可能访问不同存储上的不同容器 我想知道如何实现一个可以优化资源的连接池 我想保持对不同容器的连接打开 而不是每次尝试下载 blob 时都打开连接 谁能为我提供实
  • R:函数中使用的 ggplot2 未反映字体大小变量的变化

    我经常需要将多个不同大小的相同 ggplot2 图表输出到 png 文件 通过使用输出高度和宽度 以像素为单位 的变量 可以轻松生成每个 png 文件的大小 对于 ggplot2 部分 我使用字体大小和某些其他元素的变量 并设置一个简单的循
  • 从网站保存嵌入的 pdf

    我正在编写一个小型 C 应用程序来管理供应商提供的 化学品 安全数据表 目前 我手动搜索该化学品并保存 pdf 并在我的程序中添加指向 pdf 的链接 问题是我还有很多化学品需要处理 所以最好将过程自动化 例如 化学品的部件号如下 2710
  • 如何使用 OpenCV 检测图像帧中的对象?

    我正在使用 Raspberry Pi 开发一个漫游器 它将清扫房间并捡起掉落在地上的物体 为了检测物体 我使用了在流动站操作开始时拍摄的参考图像 以及每 10 秒单击一次的图像 新图像 为了确定图像帧是否发生变化 我在参考图像和新图像之间进