使用OpenCV和Python实现图像的颜色检测

1 背景

在这里插入图片描述

所以,我在这里。乘坐Amtrak 158火车,经过长途旅行后回家。

很热。AC几乎无法工作。婴儿在我旁边尖叫,而陪伴的母亲却孤注一掷地看着窗外,清楚地质疑生孩子是否是正确的人生决定。

最重要的是,Wi-Fi无法正常工作。

幸运的是,我带来了Game Boy和Pokemon游戏系列。

当我将可信赖的Blue版本滑入我的Game Boy时,我想:也许我可以做一点计算机视觉相关的工作,而不是与Gary Oak对抗第一千次。

老实说,仅使用颜色就能够分割每个游戏卡带真的不是很酷吗?

拿起一杯凉爽的水来对抗不能用的AC,并用一对耳塞挡住哭泣的孩子。因为在这篇文章中,我将向您展示如何使用OpenCV和Python进行颜色检测。

OpenCV和python版本:

  • Python 2.7/Python
  • OpenCV 2.4.X/OpenCV 3.0+

2 OpenCV和Python颜色检测

让我们开始吧。

打开您喜欢的编辑器并创建一个名为detect_color.py的文件:

# import the necessary packages
import numpy as np
import argparse
import cv2

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", help = "path to the image")
args = vars(ap.parse_args())

# load the image
image = cv2.imread(args["image"])

我们将从第2-4行导入必要的程序包开始,使用NumPy进行数值处理,使用argparse解析命令行参数,并使用cv2进行OpenCV绑定。

然后,第7-9行处理解析我们的命令行参数。我们只需要一个--image即可,它是image在磁盘上的存储路径。

然后,在第12行上,从磁盘加载image

现在,这是有趣的部分。

我们希望能够检测到图像中的每个Game Boy墨盒。这意味着我们必须识别图像中的红色,蓝色,黄色和灰色

让我们继续定义以下颜色列表:

# define the list of boundaries
boundaries = [
	([17, 15, 100], [50, 56, 200]),
	([86, 31, 4], [220, 88, 50]),
	([25, 146, 190], [62, 174, 250]),
	([103, 86, 65], [145, 133, 128])
]

我们在这里要做的就是在RGB颜色空间中定义一个boundaries列表(或者说BGR,因为OpenCV将图像表示为NumPy数组以相反的顺序),其中列表中的每个条目都是一个具有两个值的元组:下限上限列表。

例如,让我们看一下元组([17, 15, 100], [50, 56, 200])

在这里,我们说图像中所有具有R>=100,B>=15和G>=17以及R<=200,B<=56和G<=50的像素将被视为红色

现在我们有了boundaries列表,我们可以使用cv2.inRange函数执行实际的颜色检测了。

让我们来看看:

# loop over the boundaries
for (lower, upper) in boundaries:
	# create NumPy arrays from the boundaries
	lower = np.array(lower, dtype = "uint8")
	upper = np.array(upper, dtype = "uint8")

	# find the colors within the specified boundaries and apply
	# the mask
	mask = cv2.inRange(image, lower, upper)
	output = cv2.bitwise_and(image, image, mask = mask)

	# show the images
	cv2.imshow("images", np.hstack([image, output]))
	cv2.waitKey(0)

我们开始在第2行上遍历boundaries的上限和下限,然后在第4行和第5行上将上限和下限转换为NumPy数组。这两行似乎可以省略,当您使用OpenCV的Python绑定时,OpenCV期望这些限制为NumPy数组。此外,由于这些像素值在[0, 256]范围内,因此我们可以使用无符号8位整型数据类型。

要使用OpenCV执行实际的颜色检测,请看我们在第9行使用的cv2.inRange函数。

cv2.inRange函数需要三个参数:

  • 第一个是要执行颜色检测的图像
  • 第二个是要检测的颜色的下限
  • 第三个是要检测的颜色的上限

调用cv2.inRange之后,将返回一个二进制掩码,其中白色像素(255)表示落入上限和下限范围内的像素,而黑色像素(0)则不属于该范围。

注意:我们正在RGB颜色空间中执行颜色检测。但是您也可以在HSV或L*a*b*颜色空间中轻松地执行此操作。您只需要调整各个颜色空间的上限和下限即可。

为了创建输出图像,我们在第10行上应用了mask。该行仅调用cv2.bitwise_and,仅显示图像中在mask中具有相应白色(255)值的像素。

最后,我们在第13和14行上输出图像显示。

不错。只有14行代码,其中绝大多数是导入,参数解析和注释。

让我们继续运行脚本:

$ python detect_color.py --image pokemon_games.png

如果您的环境配置正确(意味着您已安装了带有Python绑定的OpenCV),则输出图像为:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3 总结

在这篇博客文章中,我向您展示了如何使用OpenCV和Python执行颜色检测。

要检测图像中的颜色,您需要做的第一件事就是为像素值定义上限和下限。

定义上限和下限后,然后调用cv2.inRange方法,该方法将返回一个mask,指定哪些像素落入指定的上限和下限范围内。

最后,现在有了mask,您可以使用cv2.bitwise_and函数将其应用于图像。

我的火车离家只有几站路,所以我最好把这篇文章整理一下。希望你觉得它有用!

4 完整代码

# import the necessary packages
import numpy as np
import argparse
import cv2

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", help = "path to the image")
args = vars(ap.parse_args())

# load the image
image = cv2.imread(args["image"])

# define the list of boundaries
boundaries = [
	([17, 15, 100], [50, 56, 200]),
	([86, 31, 4], [220, 88, 50]),
	([25, 146, 190], [62, 174, 250]),
	([103, 86, 65], [145, 133, 128])
]

# loop over the boundaries
for (lower, upper) in boundaries:
	# create NumPy arrays from the boundaries
	lower = np.array(lower, dtype = "uint8")
	upper = np.array(upper, dtype = "uint8")

	# find the colors within the specified boundaries and apply
	# the mask
	mask = cv2.inRange(image, lower, upper)
	output = cv2.bitwise_and(image, image, mask = mask)

	# show the images
	cv2.imshow("images", np.hstack([image, output]))
	cv2.waitKey(0)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章