创建一个遮罩,使绿色通道比蓝色和红色的通道明亮吗?

时间:2018-10-14 23:02:51

标签: numpy opencv opencv-python

我正在尝试从照片中提取绿色LED显示屏的显示,我发现,对照片进行预处理的最简单方法是通过遮罩(变黑)绿色通道不是最亮通道的所有像素。我创建了一个算法来做到这一点,但是它很慢:

> Suppressing duplicate error message. Suppressing duplicate error
> message. Suppressing duplicate error message.
> 
> --------------------------------------------------------------------------- ValueError                                Traceback (most recent call
> last) <ipython-input-3-4bf001fd75fb> in <module>()
>       2 result = pd.concat([table, vals], axis=1,); # Modin: Doesn't work
>       3 
> ----> 4 print(result)
> 
> ~/anaconda3/lib/python3.6/site-packages/modin/pandas/dataframe.py in
> __str__(self)
>     229 
>     230     def __str__(self):
> --> 231         return repr(self)
>     232 
>     233     def _repr_pandas_builder(self):
> 
> ~/anaconda3/lib/python3.6/site-packages/modin/pandas/dataframe.py in
> __repr__(self)
>     454         if len(self._row_metadata) <= 60 and \
>     455            len(self._col_metadata) <= 20:
> --> 456             return repr(self._repr_pandas_builder())
>     457         # The split here is so that we don't repr pandas row lengths.
>     458         result = self._repr_pandas_builder()
> 
> ~/anaconda3/lib/python3.6/site-packages/modin/pandas/dataframe.py in
> _repr_pandas_builder(self)
>     382         # If we don't exceed the maximum number of values on either dimension
>     383         if len(self.index) <= 60 and len(self.columns) <= 20:
> --> 384             return to_pandas(self)
>     385 
>     386         if len(self.index) >= 60:
> 
> ~/anaconda3/lib/python3.6/site-packages/modin/pandas/utils.py in
> to_pandas(df)
>     259     """
>     260     pandas_df = pandas.concat(ray.get(df._row_partitions), copy=False)
> --> 261     pandas_df.index = df.index
>     262     pandas_df.columns = df.columns
>     263     return pandas_df
> 
> ~/anaconda3/lib/python3.6/site-packages/pandas/core/generic.py in
> __setattr__(self, name, value)    3625         try:    3626             object.__getattribute__(self, name)
> -> 3627             return object.__setattr__(self, name, value)    3628         except AttributeError:    3629             pass
> 
> pandas/_libs/properties.pyx in
> pandas._libs.properties.AxisProperty.__set__()
> 
> ~/anaconda3/lib/python3.6/site-packages/pandas/core/generic.py in
> _set_axis(self, axis, labels)
>     557 
>     558     def _set_axis(self, axis, labels):
> --> 559         self._data.set_axis(axis, labels)
>     560         self._clear_item_cache()
>     561 
> 
> ~/anaconda3/lib/python3.6/site-packages/pandas/core/internals.py in
> set_axis(self, axis, new_labels)    3072             raise
> ValueError('Length mismatch: Expected axis has %d elements, '    3073 
> 'new values have %d elements' %
> -> 3074                              (old_len, new_len))    3075     3076         self.axes[axis] = new_labels
> 
> ValueError: Length mismatch: Expected axis has 8 elements, new values
> have 4 elements

如何运行它:

def mask_dominant(image, color):
    # For example, if color == "green", then we blacken out
    # all pixels where green isn't the brightest pixel
    image_copy = np.copy(image)
    black_pixel = np.array([0, 0, 0], dtype=np.uint8)
    height, width, _ = image_copy.shape
    for row in range(height):
        for col in range(width):
            # OpenCV stores colors in BGR
            b, g, r = image_copy[row, col]
            zero = False
            if color == 'blue':
                if b < g or b < r:
                    zero = True
            elif color == 'green':
                if g < b or g < r:
                    zero = True
            elif color == 'red':
                if r < b or r < g:
                    zero = True
            else:
                raise AssertionError("Color must be one of blue, green, or red")
            if zero:
                image_copy[row, col] = black_pixel
    return image_copy

上面的算法需要40秒才能在照片上运行,这太大了。是否有内置算法可以执行相同的操作或可以使用的numpy优化?

1 个答案:

答案 0 :(得分:2)

此解决方案有效:

def mask_dominant(image, color):
    # For example, if color == Green, then it blacks out
    # all pixels where green isn't the brightest pixel
    b,g,r = cv2.split(image)
    if color == 'green':
        target = g
        other1 = b
        other2 = r
    elif color == 'red':
        target = r
        other1 = g
        other2 = b
    elif color == 'blue':
        target = b
        other1 = g
        other2 = r
    else:
        raise AssertionError("invalid color: " + color)

    # Figure out which ones we need to zero & zero them
    should_zero = (target < other1) | (target < other2)
    g[should_zero] = 0
    r[should_zero] = 0
    b[should_zero] = 0

    # Merge channels back
    return cv2.merge((b,g,r))