How to map a function to every pixel in an image that is represented as a numpy array?

Viewed 524

When you use opencv-python (cv2) and read from a VideoCapture device it returns a numpy array representing the image, in my case the dimensions are (480, 640, 3). I read about vectorizing but I haven't been able to really understand it.

This is the function I wanna map

def RGBtoRGChromaticity(pixel):
    r, g, b = pixel

    total = r + g + b
    return r/total, g/total, b/total

Here is my attempt at vectorizing it, but it doesn't work :(

def RGBtoRGChromaticity(pixel):
    r, g, b = pixel

    total = ufunc.add(r, g, b)
    return ufunc.true_divide(r, total), ufunc.true_divide(g, total), ufunc.true_divide(b, total)

I am trying to take an image and find green pixels. I found this article on a color space called RG Chromaticity which, from my understanding, makes it easy to find the dominant color in each pixel. The math on the article seems to follow this idea. My main question here is how to map a function over the numpy array, but if anyone has any advice on color spaces and better ways to approach this project please don't hesitate to share!!

2 Answers

The point of vectorization is that you apply it to the whole array at once, not to each pixel.

Let's say you have

img = np.random.randint(255, size=(480, 640, 3), dtype=np.uint8)

You function then becomes

def RGBtoRGC(img):
    return img / img.sum(axis=-1, keepdims=True)

If you want the output to be uint8, I suggest rounding:

def RGBtoRGC(img):
    return np.rint(img / img.sum(axis=-1, keepdims=True), dtype=np.uint8)

How about splitting channels in map_function args? like this

import numpy as np


def RGBtoRGChromaticity(r, g, b):
    total = r + g + b
    return r / total, g / total, b / total


vfunc = np.vectorize(RGBtoRGChromaticity)
image = np.random.uniform(size=(480, 640, 3))
res = vfunc(image[:, :, 0], image[:, :, 1], image[:, :, 2])
Related