热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python识别出蓝色_放弃机器学习,Python如何进行物体检测?

学习在不使用机器学习或任何框架的情况下,如何在Python中进行物体检测。

学习在不使用机器学习或任何框架的情况下,如何在Python中进行物体检测。

387ac360edb2541ec60177a6e1b8928b.png

作者 | Ravindu Senaratne

译者 | 弯月,责编 | 屠敏

头图 | CSDN 下载自视觉中国

出品 | CSDN(ID:CSDNnews)

以下为译文:

每当我们听说“物体检测”时,就会想到机器学习和各种不同的框架。但实际上,我们可以在不使用机器学习或任何其他框架的情况下进行物体检测。在本文中,我将向你展示如何仅使用Python进行操作。

首先,我们定义一个模板图像(或者叫模板物体),然后程序将在源图像中查找与我们选择的模板匹配的所有其他物体。举例来说明一下。下面有两张图片,上面是飞机的源图像,下面是模板照片,其中的物体为飞机。

e9e6f1c37ea964de99345b147f1d71a6.png

下面我们来编写python代码,圈出源图像中所有匹配模板图像的区域。

首先,我们来检测一个物体。然后再调整代码实现多个物体的检测。

检测一个物体:最准确的那个物体

我们需要一个源图像和一个模板图像。模板图像在源图像上滑动(像2D卷积有一样),然后程序将尝试找到最准确的匹配项。

下面我们开始写代码。

import cv2

import numpy as np

from matplotlib import pyplot as plt

img_rgb = cv2.imread('SourceIMG.jpeg')

img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)

template = cv2.imread('TemplateIMG.jpeg', 0)

在上述代码中,我们使用OpenCV读取SourceIMG.jpeg和TemplateIMG.jpeg。

height, width = template.shape[::]

模板图像会在整个源图像上滑动,对整个区域进行搜索(将左上角作为参考框)。模板图像与源图像匹配后,我们记下左上角的位置,然后在实际匹配的区域周围绘制一个框。为此,我们需要知道此模板图像的高度和宽度。下面我们来绘制矩形。

res = cv2.matchTemplate(img_gray, template, cv2.TM_SQDIFF)

模板匹配是OpenCV提供的功能,它利用源图像和模板图像的灰度图像,计算我们需要的统计指标。这里我使用的是最小平方差(TM_SQDIFF),因为我们寻找的是模板图像和源图像之间的最小差。

plt.imshow(res, cmap='gray')

如果将到目前为止的结果绘制成图,就会得到一个概率图。从下图可以看到,这些小点是模板实际匹配的位置。

9fe447d9672974e871deebcfdd5c65d0.png

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

我们可以使用上面的代码从概率图中找出小点的位置。然后使用minMaxLoc(res)提取最小值、最大值、最小值的位置和最大值的位置。

top_left = min_loc

bottom_right = (top_left[0] + width, top_left[1] + height)

cv2.rectangle(img_rgb, top_left, bottom_right, (255, 0, 0), 2)

为了在模板图像匹配的源图像上绘制一个蓝色矩形,我们需要获得最小值的位置min_loc(该位置为匹配开始的位置)作为左上角。同样,我们可以通过top_left[0] + width和top_left [1] + height获得右下角。通过这些尺寸,我们可以使用cv2.rectangle绘制蓝色矩形。

一切准备就绪,下面我们进行可视化。

cv2.imshow("Matched image", img_rgb)

cv2.waitKey()

cv2.destroyAllWindows()

6e1006c79550cac5023ca423de595678.png

完整的代码:

import cv2

import numpy as np

from matplotlib import pyplot as plt

img_rgb = cv2.imread('SourceIMG.jpeg')

img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)

template = cv2.imread('TemplateIMG.jpeg', 0)

height, width = template.shape[::]

res = cv2.matchTemplate(img_gray, template, cv2.TM_SQDIFF)

plt.imshow(res, cmap='gray')

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

top_left = min_loc #Change to max_loc for all except for TM_SQDIFF

bottom_right = (top_left[0] + width, top_left[1] + height)

cv2.rectangle(img_rgb, top_left, bottom_right, (255, 0, 0), 2)

cv2.imshow("Matched image", img_rgb)

cv2.waitKey()

cv2.destroyAllWindows()

检测多个物体:在给定阈值下进行检测

上述我们已经完成了单个物体的检测,即选择源图像和模板图像之差的最小值。通过定义阈值的方法,我们可以检测所有与模板图像相似的物体。

为此,我将使用与上例相同的源图像和模板图像,并设置阈值为概率大于0.5(你可以查看res数组来确定阈值)。我们只需要更改几行代码即可检测多个物体。

res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)

在这里,我使用TM_CCOEFF_NORMED,因为我们需要获取最大值,而不是最小值。这意味着我们需要寻找多个物体而不是一个。

threshold = 0.5 #For TM_CCOEFF_NORMED, larger values means good fit

loc = np.where( res >= threshold)

我们要查找所有大于阈值的位置值。loc接收2个输出数组,并将这些数组组合在一起,这样就可以获得x,y坐标。

for pt in zip(*loc[::-1]):

cv2.rectangle(img_rgb, pt, (pt[0] + width, pt[1] + height), (255, 0, 0), 1)

这里有多个位置。因此,我们需要针对所有位置绘制蓝色矩形。下面我们来进行可视化。

2eb673d2bc7696a59e980b96946f8340.png

完整的代码:

import cv2

import numpy as np

from matplotlib import pyplot as plt

img_rgb = cv2.imread('SourceIMG.jpeg')

img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)

template = cv2.imread('TemplateIMG.jpeg', 0)

height, width = template.shape[::]

res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)

plt.imshow(res, cmap='gray')

threshold = 0.5 #For TM_CCOEFF_NORMED, larger values = good fit.

loc = np.where( res >= threshold)

for pt in zip(loc[::-1]):

cv2.rectangle(img_rgb, pt, (pt[0] + width, pt[1] + height), (255, 0, 0), 1)

cv2.imshow("Matched image", img_rgb)

cv2.waitKey()

cv2.destroyAllWindows()

看起来很简单吧?但是如果我们使用机器学习或框架,则可以达到更高的准确性。

感谢您的阅读,希望本文对您有所帮助。

原文:https://towardsdatascience.com/object-detection-on-python-using-template-matching-ab4243a0ca62

本文为 CSDN 翻译,转载请注明来源出处。


版权声明:本文为weixin_36179941原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_36179941/article/details/113677507
推荐阅读
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • Windows7 64位系统安装PLSQL Developer的步骤和注意事项
    本文介绍了在Windows7 64位系统上安装PLSQL Developer的步骤和注意事项。首先下载并安装PLSQL Developer,注意不要安装在默认目录下。然后下载Windows 32位的oracle instant client,并解压到指定路径。最后,按照自己的喜好对解压后的文件进行命名和压缩。 ... [详细]
author-avatar
手机用户2502913717
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有