When an OpenCV image is inputted as 3-channel image, according to the source code
only first channel is used to decode the QR Code (which is generally the Blue channel in OpenCV channel ordering) and it leads to different decoding result than inputting a 3-channel PIL image. However, if a grayscale OpenCV image is inputted, the decoding results are consistent with the PIL image. Here is the code snippet that reproduces this case (you can use the attached image to see the behavior):
import cv2
from PIL import Image
from pyzbar.pyzbar import decode
img = cv2.imread("test_qr.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
result_opencv_gray= decode(img)
img = cv2.imread("test_qr.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
im_pil = Image.fromarray(img)
result_pil= decode(im_pil)
img = cv2.imread("test_qr.jpg")
result_opencv_bgr= decode(img)
print(result_opencv_bgr)
print(result_pil)
print(result_opencv_gray)
# result_pil and result_opencv_gray are consistent but result_opencv_bgr is not the same
When an OpenCV image is inputted as 3-channel image, according to the source code only first channel is used to decode the QR Code (which is generally the Blue channel in OpenCV channel ordering) and it leads to different decoding result than inputting a 3-channel PIL image. However, if a grayscale OpenCV image is inputted, the decoding results are consistent with the PIL image. Here is the code snippet that reproduces this case (you can use the attached image to see the behavior):