inverting image in Python with OpenCV
Solution 1
You almost did it. You were tricked by the fact that abs(imagem-255)
will give a wrong result since your dtype
is an unsigned integer. You have to do (255-imagem)
in order to keep the integers unsigned:
def inverte(imagem, name):
imagem = (255-imagem)
cv2.imwrite(name, imagem)
You can also invert the image using the bitwise_not
function of OpenCV:
imagem = cv2.bitwise_not(imagem)
Solution 2
Alternatively, you could invert the image using the bitwise_not
function of OpenCV:
imagem = cv2.bitwise_not(imagem)
I liked this example.
Solution 3
You can use "tilde" operator to do it:
import cv2
image = cv2.imread("img.png")
image = ~image
cv2.imwrite("img_inv.png",image)
This is because the "tilde" operator (also known as unary operator) works doing a complement dependent on the type of object
for example for integers, its formula is:
x + (~x) = -1
but in this case, opencv use an "uint8 numpy array object" for its images so its range is from 0 to 255
so if we apply this operator to an "uint8 numpy array object" like this:
import numpy as np
x1 = np.array([25,255,10], np.uint8) #for example
x2 = ~x1
print (x2)
we will have as a result:
[230 0 245]
because its formula is:
x2 = 255 - x1
and that is exactly what we want to do to solve the problem.
Solution 4
You can also do it with numpy.
import cv2
import numpy as np
image = cv2.imread('your_image', 0)
inverted = np.invert(image)
cv2.imwrite('inverted.jpg', inverted)
Comments
-
Mansueli over 2 years
I want to load a color image, convert it to grayscale, and then invert the data in the file.
What I need: to iterate over the array in OpenCV and change every single value with this formula (it might be wrong but it seems reasonable for me):
img[x,y] = abs(img[x,y] - 255)
but I don't understand why doesn't it works:
def inverte(imagem, name): imagem = abs(imagem - 255) cv2.imwrite(name, imagem) def inverte2(imagem, name): for x in np.nditer(imagem, op_flags=['readwrite']): x = abs(x - 255) cv2.imwrite(name, imagem) if __name__ == '__main__': nome = str(sys.argv[1]) image = cv2.imread(nome) gs_imagem = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) inverte(gs_imagem, "invertida.png") inverte2(gs_imagem, "invertida2.png")
I don't want to do an explicit loop (I am trying to be more pythonic). I can see that in one image that got a white background it turned black, but only this it doesn't looks like the other colors are having much (if any) change.
-
grooveplex about 5 yearsI think your answer would be better if you explained a bit why this works.
-
bongbang over 4 years"255" should replace "256" in "x2 = 256 - x1".