【问题标题】:python - check presence of predefined color ranges in imagepython - 检查图像中是否存在预定义的颜色范围
【发布时间】:2022-06-13 17:40:44
【问题描述】:

我需要验证图像文件中是否存在某些预定义颜色范围以及存在多少。

每个颜色范围由 colorRange 类中的 6 个变量和一个计数器定义:

hS (hue start)
hE (hue end)
sS (saturation start)
sE (saturation end)
lS (lightness start)
lE (lightness end)
colorCounter

图像可以是文件,也可以是从相机加载的。以下代码从相机缓冲区加载图像:

img1 = np.ndarray(buffer=component.data.copy(), dtype=np.uint8,
                                     shape=(component.height, component.width, 1))
img2 = cv2.cvtColor(img1, cv2.COLOR_BayerBG2BGR)

我需要做的是扫描每个第 n 个像素(5 是一个很好的起始值),并将其与每个颜色范围进行比较。如果它属于该颜色范围,则将 +1 添加到特定的colorCounter。最后,我检查了每个颜色范围的计数器并以百分比计算该颜色范围的存在。目标是检查落入每个颜色范围的分析像素的百分比。颜色范围的总和可以大于 100,因为一个像素可以落入多个颜色范围,因为它们可以重叠。 (例如,一个颜色可能是所有的红色,另一个可能只是深红色。一个深红色的像素会落在这两个范围内,一个鲜红色的像素只在第一个范围内。)

我这样做的方法是一个一个地检查每五个像素,将其 rgb 值转换为 HSL,然后将其与所有颜色范围进行比较。 (如果 hS > hE 那么它会在红色中环绕)

但这似乎是一种非常复杂的方法,并且想知道是否有一些预制函数可以做到这一点,或者至少部分做到这一点。

所以问题是:如何以聪明的方式做到这一点?

更新:

这是我目前所拥有的:

    hls = cv2.cvtColor(img2, cv2.COLOR_BGR2HLS)
    
    GreenLo = np.array([75, 0, 0])
    GreenHi = np.array([155, 1, 1])

    pxGreen = cv2.inRange(hls[0:620:5, 0:620:5], GreenLo, GreenHi)
    cGreen = cv2.countNonZero(pxGreen)

【问题讨论】:

  • 请问您的列表中有多少种颜色?
  • @MarkSetchell 未定义。可以是 10 或 20.. 甚至 30.. 超过 30 的可能性很小...
  • 只需为列表中的每种颜色运行cv2.inRange() 并计算真(非零)像素docs.opencv.org/4.x/d2/de8/…
  • @MarkSetchell 感谢您的评论,但我不确定我是否理解您的意思。像素必须在 3 个边界内。(h、s 和 l)。您能否发布一个简短的示例代码作为答案?
  • 和这个一样... stackoverflow.com/a/50215020/2836621 除了你把这行image[mask>0]=(0,0,255)改成cv2.countNonZero(...)

标签: python colors cv2 hsl


【解决方案1】:

我听从了@Mark Setchell 的建议,想出了这个解决方案:

颜色类:

class crateColor(QObject):
cName: str
cId: int
pId: int
hHi: int
hLo: int
lHi: int
lLo: int
sHi: int
sLo: int
pxCnt: int
perc: float

采用的解决方案:

    green = crateColorClass.crateColor()
    green.cName = "EU green"
    green.cId = 1
    green.pId = 1
    green.hLo = 65
    green.hHi = 165
    green.lLo = 20
    green.lHi = 95
    green.sLo = 20
    green.sHi = 100
    colorList.append(green)   # REPEATING THIS FOR EACH COLOR.


    x1 = 170 # DEFINING THE AREA AND POSITION I AM INTERESTED IN AND EVERY Nth. PIXEL
    x2 = 470
    y1 = 520
    y2 = 610
    i = 5

    dx = x2-x1
    dy = y2-y1
    a = int(dx/i)*int(dy/i)


    for c in colorList:
         if c.hLo > c.hHi: # wrap around 360 for red.
             Lo = np.array([c.hLo, c.lLo*2.55, c.sLo*2.55]) # *2.55 to have S and L 0 to 100
             Hi = np.array([359, c.lHi*2.55, c.sHi*2.55])
             px = cv2.inRange(hls[y1:y2:i, x1:x2:i], Lo, Hi)
             c.pxCnt = cv2.countNonZero(px)
             Lo = np.array([0, c.lLo * 2.55, c.sLo * 2.55])
             Hi = np.array([c.hHi, c.lHi * 2.55, c.sHi * 2.55])
             px = cv2.inRange(hls[y1:y2:i, x1:x2:i], Lo, Hi)
             c.pxCnt = c.pxCnt + cv2.countNonZero(px)
             c.perc = (c.pxCnt/a)*100
         else:
             Lo = np.array([c.hLo, c.lLo*2.55, c.sLo*2.55])
             Hi = np.array([c.hHi, c.lHi*2.55, c.sHi*2.55])
             px = cv2.inRange(hls[y1:y2:i, x1:x2:i], Lo, Hi)
             c.pxCnt = cv2.countNonZero(px)
             c.perc = (c.pxCnt/a)*100
         print("cName, cId, perc, pxCnt: ", c.cName, c.cId, c.perc, c.pxCnt)

【讨论】:

    猜你喜欢
    • 2018-11-22
    • 2011-07-17
    • 1970-01-01
    • 2017-11-14
    • 1970-01-01
    • 1970-01-01
    • 2019-05-12
    • 2015-11-21
    • 2012-11-11
    相关资源
    最近更新 更多