0

As you know looping through each pixels and accessing their values with opencv takes too long. As a beginner I'm trying to learn opencv myself when I tried this approach it took me around 7-10 seconds of time to loop through image and perform operations.

code is as below

original_image = cv2.imread(img_f)

image = np.array(original_image)
for y in range(image.shape[0]):
    for x in range(image.shape[1]):
        # remove grey background
        if 150 <= image[y, x, 0] <= 180 and \
                150 <= image[y, x, 1] <= 180 and \
                150 <= image[y, x, 2] <= 180:
            image[y, x, 0] = 0
            image[y, x, 1] = 0
            image[y, x, 2] = 0

        # remove green dashes
        if image[y, x, 0] == 0 and \
                image[y, x, 1] == 169 and \
                image[y, x, 2] == 0:
            image[y, x, 0] = 0
            image[y, x, 1] = 0
            image[y, x, 2] = 0

in above code i'm just trying to remove grey and green pixel colors.

I found similar question asked here but im not able to understand how to use numpy in my usecase as i'm beginner in python and numpy.

Any help or suggestion for solving this will be appreciated thanks

2

3 Answers 3

3

You can take advantage of NumPy's vectorized operations to eliminate all loops which should be much faster.

# Remove grey background
is_grey = ((150 <= image) & (image <= 180)).all(axis=2, keepdims=True)
image = np.where(is_grey, 0, image)

# Remove green dashes
is_green_dash = (image[..., 0] == 0) & (image[..., 1] == 169) & (image[..., 2] == 0)
is_green_dash = is_green_dash[..., np.newaxis]  # append a new dim at the end
image = np.where(is_green_dash, 0, image)

Both invocations of np.where rely on NumPy's broadcasting.

Sign up to request clarification or add additional context in comments.

Comments

0

You can apply numpy filtering to image. In your scenario it would be:

mask_gray = (
    (150 <= image[:, :, 0]) & (image[:, :, 0] <= 180) & 
    (150 <= image[:, :, 1]) & (image[:, :, 1] <= 180) & 
    (150 <= image[:, :, 2]) & (image[:, :, 2] <= 180)
)

image[mask_gray] = 0

mask_green = (
    (image[:, :, 0] == 0) &
    (image[:, :, 1] == 169) &
    (image[:, :, 2] == 0)
)

image[mask_green] = 0

mask_gray and mask_green here are boolean masks

Comments

0

If you insist on writing your own loops...

You could just use numba. It's a JIT compiler for Python code.

from numba import njit

@njit
def your_function(input):
    ...
    return output

input = cv.imread(...) # yes this will shadow the builtin of the same name
output = your_function(input)

The first time you call your_function, it'll take a second to compile. All further calls are blazingly fast.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.