OpenCv 反演:BGR 到 HSV,然后回到 BGR - 我不应该得到相同的图像吗?
OpenCv inversion: BGR to HSV then back to BGR - shouldn't I get the same image?
例如,当我 运行 这个:
import cv2
import numpy as np
from collections import Counter
# load image, calculate some basic stats
path = 'path/to/my/image.png'
bgr_img = cv2.imread(path)
h, w, c = bgr_img.shape
print("There are %d entries in this %d channel image" % (h*w*c, c))
# convert and then invert, we should get the same image
bgr_img2 = cv2.cvtColor(cv2.cvtColor(bgr_img, cv2.COLOR_BGR2HSV), cv2.COLOR_HSV2BGR)
print("all entries match: %s" % np.all(bgr_img == bgr_img2))
# hmm, we don't. let's see where the differences are
mismatches = np.where(bgr_img != bgr_img2)
print("there are %d mismatched entries" % len(mismatches[0]))
print("mismatches are along the following channels: %s" % Counter(mismatches[2]))
# ok, clearly lots of them. maybe they're all just off by 1 or 2?
mm = zip(mismatches[0], mismatches[1], mismatches[2])
differences = []
for x, y, c in mm:
diff = bgr_img[x, y, c] - bgr_img2[x, y, c]
differences.append(diff)
print(differences)
我得到以下输出:
There are 1228800 entries in this 3 channel image
all entries match: False
there are 524511 mismatched entries
mismatches are along the following channels: Counter({1: 270572, 0: 253939})
[1, 1, 1, 254, 1, 254, 1, 3, 1, 3, 1, 3, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 1, 3, 1, 3, 1, 3, 1, 254, 1, 254, 254, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, ...]
我看到了几种可能性。首先是 BGR -> HSV 转换不是严格可逆的。另一个是我错误地使用了 OpenCV。是哪个?
您应该得到几乎相同的图像,但除非在边缘情况下,否则不会得到相同的位。 BGR 到 HSV(和返回)涉及 space 之间的转换,这些转换在其他 space 中的所有值都没有相同的表示。会出现小的舍入误差。
请参阅 https://docs.opencv.org/3.4/df/d9d/tutorial_py_colorspaces.html 中有关色相范围为 [0, 179] 的注释。如果您考虑一下,这意味着从 BGR(或 RGB)转换时会丢失信息。您无法可靠地取回这些位。
例如,当我 运行 这个:
import cv2
import numpy as np
from collections import Counter
# load image, calculate some basic stats
path = 'path/to/my/image.png'
bgr_img = cv2.imread(path)
h, w, c = bgr_img.shape
print("There are %d entries in this %d channel image" % (h*w*c, c))
# convert and then invert, we should get the same image
bgr_img2 = cv2.cvtColor(cv2.cvtColor(bgr_img, cv2.COLOR_BGR2HSV), cv2.COLOR_HSV2BGR)
print("all entries match: %s" % np.all(bgr_img == bgr_img2))
# hmm, we don't. let's see where the differences are
mismatches = np.where(bgr_img != bgr_img2)
print("there are %d mismatched entries" % len(mismatches[0]))
print("mismatches are along the following channels: %s" % Counter(mismatches[2]))
# ok, clearly lots of them. maybe they're all just off by 1 or 2?
mm = zip(mismatches[0], mismatches[1], mismatches[2])
differences = []
for x, y, c in mm:
diff = bgr_img[x, y, c] - bgr_img2[x, y, c]
differences.append(diff)
print(differences)
我得到以下输出:
There are 1228800 entries in this 3 channel image
all entries match: False
there are 524511 mismatched entries
mismatches are along the following channels: Counter({1: 270572, 0: 253939})
[1, 1, 1, 254, 1, 254, 1, 3, 1, 3, 1, 3, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 1, 3, 1, 3, 1, 3, 1, 254, 1, 254, 254, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, ...]
我看到了几种可能性。首先是 BGR -> HSV 转换不是严格可逆的。另一个是我错误地使用了 OpenCV。是哪个?
您应该得到几乎相同的图像,但除非在边缘情况下,否则不会得到相同的位。 BGR 到 HSV(和返回)涉及 space 之间的转换,这些转换在其他 space 中的所有值都没有相同的表示。会出现小的舍入误差。
请参阅 https://docs.opencv.org/3.4/df/d9d/tutorial_py_colorspaces.html 中有关色相范围为 [0, 179] 的注释。如果您考虑一下,这意味着从 BGR(或 RGB)转换时会丢失信息。您无法可靠地取回这些位。