Fedour Traktor
Fedour Traktor

Reputation: 331

Opencv Python: Fastest way to multiply pixel value

I'm trying to change the pixel value of an image.

I have a factor r, g and b which will be used to multiply the pixel values ​​of this image.

import cv2
import numpy as np
from matplotlib import pyplot as plt
import time

im = cv2.imread("boat.jpg")
im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
im = cv2.resize(im, (4096,4096))

r_factor = 1.10
g_factor = 0.90
b_factor = 1.15


start = time.time()
im[...,0] = cv2.multiply(im[...,0], r_factor)
im[...,1] = cv2.multiply(im[...,1], g_factor)
im[...,2] = cv2.multiply(im[...,2], b_factor)
end = time.time()

This process takes time on large images. Is there any other method to multiply the value of the pixels ?

Upvotes: 0

Views: 1159

Answers (1)

Mark Setchell
Mark Setchell

Reputation: 207425

If I do this on my system, I get 568 ms:

import cv2
import numpy as np

# Known start image
im = np.full((4096,4096,3), [10,20,30], np.uint8)

In [49]: %%timeit
    ...: im[...,0] = cv2.multiply(im[...,0], r_factor)
    ...: im[...,1] = cv2.multiply(im[...,1], g_factor)
    ...: im[...,2] = cv2.multiply(im[...,2], b_factor)
    ...: 
    ...: 
568 ms ± 16 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

If I do it like this, it takes 394 ms:

In [42]: %timeit res = cv2.multiply(im,(r_factor, g_factor,b_factor,0))
394 ms ± 12.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

You may get faster results doing it in-place, i.e. by specifying dst=im in the call. If I specify the type of the result, it comes out 5x faster at 63 ms - there must be something SIMD going on under the covers:

%timeit _ = cv2.multiply(im,(r_factor, g_factor,b_factor,0), dst=im, dtype=1)
63 ms ± 79.1 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

If you are really keen on making it even faster, look at some answers tagged with [numba].

Upvotes: 2

Related Questions