【问题标题】:finding colors in Image and redraw on second image(using numpy)在图像中查找颜色并在第二张图像上重绘(使用 numpy)
【发布时间】:2013-05-20 21:34:09
【问题描述】:

我正在尝试在图片中查找特定颜色(或更可能的颜色范围)并在第二张图片上重新绘制坐标以进行进一步调查。因为我读了很多关于 numpy 有多棒的文章,所以我开始使用它(我对 python 非常陌生,尤其是 numpy)。 所以,我写了一些东西,它适用于一种颜色,但是有很多颜色的(性能)问题,我很确定,我可以通过使用 numpy 提供的更多功能来解决这个问题。基本上,我想杀死 for 循环。这是我的代码(我必须稍后添加更多颜色范围):

import PIL, numpy
from PIL import Image

def add_color_range(p_a_c, r,r1,g,g1,b,b1):
    for ir in range(r, r1+1):
        for ig in range(g, g1+1):
            for ib in range(b, b1+1):
                p_a_c.extend([[ir,ig,ib]])
    return p_a_c

for i in range(1):
    im = Image.open('%*s.bmp'% (1, i))
    n_test = numpy.asarray(im)
    ni_test = numpy.zeros([1050,1680,3],dtype=numpy.uint8)
    ni_test.fill(255)
    c=[]
    c=add_color_range(c,5,10,5,10,5,10)

    for ic in range(len(c)):
        ind=numpy.where(numpy.all(n_test==c[ic],  axis=-1))
        for ii in range(len(ind[0])):
            ni_test[ind[0][ii],ind[1][ii]]=[0,0,0]
    im_test = Image.fromarray(ni_test, 'RGB')
    im_test.save('test_%*s.bmp'% (1, i))

【问题讨论】:

    标签: python image numpy colors find


    【解决方案1】:
    import PIL
    import Image
    import numpy as np
    
    i = 0
    im = Image.open('%*s.bmp' % (1, i)).convert('RGB')
    n_test = np.asarray(im)
    r, g, b = np.rollaxis(n_test, axis=-1)
    ni_test = np.empty(n_test.shape[:2], dtype=np.uint8)
    ni_test.fill(255)
    
    mask = (r >= 5) & (r <= 10) & (g >= 5) & (g <= 10) & (b >= 5) & (b <= 10)
    ni_test[mask] = 0
    im_test = Image.fromarray(ni_test, '1')
    im_test.save('test_%*s.bmp' % (1, i))
    

    说明:

    如果我正确地理解了您的代码,那么您正在寻找颜色在特定范围内的点。为三个 RGB 通道中的每一个定义变量会很方便:

    r, g, b = np.rollaxis(n_test, axis=-1)
    

    如果n_test.shape(w, h, 3),那么rgb 的形状分别是(w, h)n_test 是 3D 数组,而 r、g,b` 都是 2D 数组。

    现在我们可以通过定义颜色范围的不等式来消除所有for-loops,而不是使用np.where 并选择与特定颜色相关的点:

    mask = (r >= 5) & (r <= 10) & (g >= 5) & (g <= 10) & (b >= 5) & (b <= 10)
    

    每个括号表达式,例如(r &gt;= 5),返回一个与r(即(w, h))形状相同的二维布尔数组。 &amp; 按元素应用逻辑和运算符。所以mask 也是一个二维布尔数组。只要所有这些括号表达式都为真,它就为真。

    ni_test[mask] = 0 使用二维布尔数组 mask 索引二维数组 ni_test。它将 0 分配给 ni_testmask 为 True 的位置。

    【讨论】:

    • 好的,谢谢,效果很好。我正在等待一段时间,如果其他人有其他建议,但我认为,差不多就是这样。
    • 我遇到了另一个问题。结果,我想要一张单时图片,而不是 RGB 图片。我尝试了一些东西,但它给了我奇怪的结果。到目前为止有效的方法是在 Image.fromarray(ni_test, 'RGB') 中添加 .convert('1'),但这意味着,我创建了一个 RGB 图片然后对其进行转换,而不是创建一个单时 -首先是图片。
    • 我已修改代码以输出单色图像。为此,我给ni_test 提供了n_test.shape[:2] 的形状,然后在L 模式下将其转换为PIL 图像。
    • 我尝试了同样的方法,但我使用了模式 '1'。这并没有什么不同。
    猜你喜欢
    • 2022-06-14
    • 2014-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多