Look at this code,
img = cv2.imread("image2.jpg",0)
img_str = cv2.imencode('.jpg', img)[1] #Encodes and stores in buffer
print(img_str)
#for i,item in enumerate(img_str): } THIS
# img_str[i] = 255-item } IS CONFUSING
nparr = np.frombuffer(img_str, np.uint8)
img2 = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
My question is without this,
#for i,item in enumerate(img_str): } THIS
# img_str[i] = 255-item } IS CONFUSING
The code runs fine imdecode returns the same! But however when I uncomment it imdecode returns None
Opencv docs say
If the buffer is too short or contains invalid data, the empty matrix/image is returned.
What exactly is the invalid data that makes imdecode return none? Or any other mistake?
cv2. imdecode() function reads data from specified memory cache and converts (decodes) data into image format; it is mainly used to recover images from network transmission data. cv2.
imdecode() function is used to read image data from a memory cache and convert it into image format. This is generally used for loading the image efficiently from the internet. Syntax: cv2.imdecode(buf,flags)
I misunderstood your question before, but now your comments make it clearer.
When you encode an image in '.jpg' it is not a pixel array as before, but an array of bytes that represents a jpeg image. It will be the equivalent to read the bytes of the image directly with native functions.
If you transform each byte, it won't be able to decode it correctly, and your data will be invalid.
Let's examine the data a little bit more carefully:
First, we load the image and encode the data
# Exactly what you have to load and encode
import cv2
import numpy as np
img = cv2.imread("image2.jpg",0)
img_str = cv2.imencode('.jpg', img)[1]
Now, lets flatten the image array and see the first 10 pixels ( I use a random image I had in my drive):
img.flatten()[0:10]
This gives me:
[191, 191, 191, 191, 191, 191, 191, 191, 191, 191]
Now, lets show the first 10 bytes of the encoded one:
print(img_str.flatten()[0:10])
And I get:
[255 216 255 224 0 16 74 70 73 70]
As you can see, it is totally different numbers as before.... and not only that, At least the 2 first bytes gives information about the image as it is explain in the link I put a little before.
Start of image is the following code:
0xFF, 0xD8
That if you put it in decimal numbers it will give you:
255 216
Which is the first 2 bytes of the byte array... If you subtract 255-byte
for all bytes, then the initial part will be 0 39
which will be an invalid syntax for the decoder to parse it.
In conclusion, do not change the image bytes after encoding it, change them before encoding it if needed, and try to also use OpenCV's function or from numpy to do it faster, the loop takes quite long in python. To invert the image and then encode it is the following code:
import cv2
import numpy as np
img = cv2.imread("image2.jpg",0)
invImg = cv2.bitwise_not(img) # equivalent to 255-img
img_str = cv2.imencode('.jpg', invImg )[1]
img2 = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
Another thing to consider, if you have an image and encode it and decode it in jpg, it WON'T BE THE SAME IMAGE, because jpg is a lossy compression, and it will have some small differences.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With