There's a fundamental misconception here about the way images are stored and what lossy/lossless means.
Let's imagine we have a really simple 1-pixel grey image and that pixel has brightness 100. Let's make our own format for storing our image... I'm going to choose to store it as a Python script. Ok, here's our file:
print(100)
Now, let's do another lossless version, like PNG might:
print(10*10)
Now we have recreated our image losslessly, because we still get 100, but the MD5 hash is clearly going to be different. PNG does filtering before compressing and it checks whether each pixel is similar to the ones above and to the left in order to save space. One encoder might decide it can do better by looking at the pixel above, another one might think it can do better by looking at the pixel to the left. The result is the same.
Now let's make a new version of the file that stores the image:
# Updated 2022-08-12T21:15:46.544Z
print(100)
Now there's a new comment. The metadata about the image has changed, and so has the MD5 hash. But no pixel data has changed so it is a lossless change. PNG images often store the date/time in the file like this, so even two bit-for-bit identical images will have a different hash for the same pixels if saved 1 second apart.
Now let's make our single pixel image like a JPEG:
print(99)
According to JPEG, that'll look pretty similar, and it's 1-byte shorter, so it's fine. How do you think the MD5 hash will compare?
Now there's a different JPEG library, it thinks this is pretty close too:
print(98)
Again, the image will appear indistinguishable from the original, but your MD5 hash will be different.
TL/DR;
If you want an identical, bitwise perfect copy of your file, use the copy
command.
Further food for thought... when you read an image with OpenCV, you actually get a Numpy array of pixels, don't you. Where is the comment that was in your image? The copyright? The GPS location? The camera make and model and shutter speed? The ICC colour profile? They are not in your Numpy array of pixels, are they? They are lost. So, even if the PNG/JPEG encoder made exactly the same decisions as the original encoder, your MD5 hash would still be different because all that other data is missing.