Problem
An image is an array, so you can use Python or a library, like Numpy, to avoid using for loops.
Gazing the grayscale Wiki, it is possible to check the following formula: Y = 0.2126 * R + 0.7152 * G + 0.0722 * B
.
Python can be used with Slice in the matrix. Where each pixel of an image is composed as follows [linha, coluna, canal]
. And an image in the RGB color space has three channels, R,G and B. Therefore, each pixel has an array representing the channel (R,G,B)
.
But note that Opencv uses BGR by default
((B,G,R)
)
Then it is possible to check the optimization with the following code:
import time
import cv2
import numpy as np
import urllib.request
# Carregar imagem da internet
resp = urllib.request.urlopen("https://i.stack.imgur.com/OWQJc.jpg")
imagem = np.asarray(bytearray(resp.read()), dtype="uint8")
imagem = cv2.imdecode(imagem, cv2.IMREAD_COLOR)
# Carregar imagem do PC
# imagem = cv2.imread("goku-jr.jpg")
# FOR LOOPS
start_time = time.time()
for coluna in imagem:
for pixel in coluna:
media = int(sum(pixel)/3)
pixel [0] = media
pixel [1] = media
pixel [2] = media
cv2.imwrite("OWQJc1.jpg",imagem)
print("--- %s segundos ---" % (time.time() - start_time))
# MATRIZES E ARRAYS
# Carregar imagem da internet
resp = urllib.request.urlopen("https://i.stack.imgur.com/OWQJc.jpg")
imagem = np.asarray(bytearray(resp.read()), dtype="uint8")
imagem = cv2.imdecode(imagem, cv2.IMREAD_COLOR)
# Carregar imagem do PC
# imagem = cv2.imread("goku-jr.jpg")
start_time = time.time()
imagem = 0.0722 * imagem[:, :, 0] + 0.7152 * imagem[:, :, 1] + 0.2126 * imagem[:, :, 2]
imagem = imagem.astype(np.uint8)
cv2.imwrite("OWQJc2.jpg",imagem)
print("--- %s segundos ---" % (time.time() - start_time))
Upshot
On my computer, the following result was obtained:
--- 0.2000114917755127 segundos ---
--- 0.008000612258911133 segundos ---
It is possible to verify that the method using the for loops is slightly wrong by comparing the following images:
Result 1:
Score 2:
What would be the object
imagem2
?– Woss
I got the name wrong.
– LucasElias
About the
for
within thefor
: there is no problem with this. In the amount of pixels, your program runs in linear time. It just so happens that to see the pixels, you need to navigate the columns separately, but this does not imply that your program runs in quadratic time relative to the number of pixels. I talk about it more in that reply– Jefferson Quesado
I think you can use the itertools module, it has the chain, but it will only decrease a line in your code, or even that, if you count the import
– Elton Nunes
"On the nail" means that
cv2.cvtColor(imagem, cv2.COLOR_BGR2GRAY)
does not serve?– Augusto Vasques