检测图像中特定区域的颜色 Nodejs OpenCV

4
我正在尝试编写代码来检测图像中特定区域的颜色。目前我发现使用OpenCV可以做到这一点,但是还没有找到任何特定的教程来帮助此操作。我想用JavaScript来做这个,但我也可以使用Python OpenCV获得结果。请问有谁能分享任何有用的链接或者解释如何实现在图像中检测特定区域的颜色呢?
例如: enter image description here 红色框里显示了一个不同的颜色,我需要弄清楚它显示的是什么颜色。
我尝试过使用OpenCV Canny图像,虽然成功地用Canny图像分离了面积,但如何检测该特定Canny区域的颜色仍然是一个挑战。另外,我也尝试使用OpenCV中的inRange方法,效果很好。
# 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]))

它的功能很好,能够从图像中提取颜色区域。但是否有回调函数可以响应图像是否具有特定颜色,以便可以自动完成所有操作?

1
如果这对你来说是一个挑战,你可能需要先阅读一本书……老派但非常有效。如果你想要处理一张图片的帮助,请发布该图片,提供你的代码,解释你期望发生什么以及实际发生了什么。仅仅询问一般性建议会使你的问题因为过于宽泛而被关闭。 - Piglet
是的,我正在更新问题。 - AndroConsis
解决这个问题的方法高度取决于图像。它是否总是只有两种不同的颜色?较小的区域是否总是在中心的正方形?有许多完全自动化的方法,但使用哪种方法取决于图像。如果您只是好奇存在哪些颜色,可以简单地创建直方图。 - Piglet
@Prateek...如果我没记错的话,你想要在所选正方形区域内具有异构像素颜色的情况下,实现动态阈值触发,并设定最小或最大值,对吗? - ZF007
@ZF007准确无误地理解了它。 - AndroConsis
显示剩余6条评论
3个回答

3

我假设您已经知道要动态更改的rect的位置,并且需要找出所需ROI中最占优势的颜色。有许多方法可以做到这一点,其中一种方法是获取ROI中所有像素的平均值,另一种方法是计算给定ROI中所有不同的像素值,带有一些容差差异。

方法1:

import cv2
import numpy as np

img = cv2.imread("path/to/img.jpg")
region_of_interest = (356, 88, 495, 227) # left, top, bottom, right

cropped_img = img[region_of_interest[1]:region_of_interest[3], region_of_interest[0]:region_of_interest[2]]

print cv2.mean(cropped_img)
>>> (53.430516018839604, 41.05708814243569, 244.54991977640907, 0.0)

方法2:

为了找到给定图像中的各种主要聚类,您可以使用cv2.kmeans()函数:

import cv2
import numpy as np

img = cv2.imread("path/to/img.jpg")
region_of_interest = (356, 88, 495, 227)

cropped_img = img[region_of_interest[1]:region_of_interest[3], region_of_interest[0]:region_of_interest[2]]
Z = cropped_img.reshape((-1, 3))

Z = np.float32(Z)

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 4
ret, label, center = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)

# Sort all the colors, as per their frequencies, as:
print center[sorted(range(K), key=lambda x: np.count_nonzero(label == [x]), reverse=True)[0]]
>>> [  52.96525192   40.93861389  245.02325439]

0

我不确定你为什么需要在这种情况下使用回调函数,但也许这就是你的意思?

def test_color(image, lower, upper):
    mask = cv2.inRange(image, lower, upper)
    return np.any(mask == 255)

解释:

  • cv2.inRange()函数在像素位于范围(lower, upper)内时返回255,否则返回0(请参见docs
  • 使用np.any()检查mask中是否有任何元素实际上为255

0

@Prateek... 很高兴将问题缩小到核心。您提供的代码并未解决当前问题,仅仅是一个问题。我会给您指引方向,但您必须自己编写代码。

以下是指导您获得脚本结果的步骤:

1)在脚本中添加两个像素列表(过去和现在),以存储值(像素类型+出现次数)。

2)引入一个 while 循环,带有真/停止语句的操作(链接到“3”),用于循环目的,因为这样它就成为了一个动态过程。

3)编写带有闪亮警告横幅的 GUI。

4)将 pixellist 与 current_pixellist 进行比较,以进行严重状态更改(阈值)。

5)如果“4”处的 delta 状态更改符合阈值,则抛出警报(“3”)。

当您编写好代码并享受追踪 traceback 的麻烦后……然后编辑您的问题,使用代码更新它并重新塑造您的问题(如果您愿意,我可以帮助您)。然后我们可以从那里开始。听起来不错吧?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接