Kos*_*osh 6 opencv image-processing python-3.x
我一直认为将图像从彩色转换为灰度很简单:每个像素的强度将是每个颜色通道强度的平均值。但我注意到了这一点,cv2.COLOR_RGB2GRAY并cv2.COLOR_BGR2GRAY给出了不同的结果。当我用它们进行试验时,我还发现它也不同于每个颜色通道的强度平均值。
PS当我发现时我完全感到困惑
img_read_as_color[:,:,0]/3+img_read_as_color[:,:,1]/3+img_read_as_color[:,:,2]/3 == (img_read_as_color[:,:,0]+img_read_as_color[:,:,1]+img_read_as_color[:,:,2])/3
Run Code Online (Sandbox Code Playgroud)
但是当显示为图像时
(img_read_as_color[:,:,0]+img_read_as_color[:,:,1]+img_read_as_color[:,:,2])/3
Run Code Online (Sandbox Code Playgroud)
看起来像
img_read_as_color[:,:,0]+img_read_as_color[:,:,1]+img_read_as_color[:,:,2]
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释为什么会这样吗?
我的完整代码:
import matplotlib.pyplot as plt
import cv2
sample = r'G:\Python\knight-mare\screenshots\2020-07-12-02-40-44.jpg'
img_read_as_grayscale = cv2.imread(sample, cv2.IMREAD_GRAYSCALE)
img_read_as_color = cv2.imread(sample, cv2.IMREAD_COLOR)
img_RGB_to_grayscale = cv2.cvtColor(img_read_as_color, cv2.COLOR_RGB2GRAY)
img_BGR_to_grayscale = cv2.cvtColor(img_read_as_color, cv2.COLOR_BGR2GRAY)
plt.imshow(img_read_as_grayscale)
plt.title('img_read_as_grayscale')
plt.show()
plt.imshow(img_read_as_color)
plt.title('img_read_as_color')
plt.show()
plt.imshow(img_RGB_to_grayscale)
plt.title('img_RGB_to_grayscale')
plt.show()
plt.imshow(img_BGR_to_grayscale)
plt.title('img_BGR_to_grayscale')
plt.show()
channel_avg_div_separately = img_read_as_color[:,:,0]/3+img_read_as_color[:,:,1]/3+img_read_as_color[:,:,2]/3
channel_avg_div_together = (img_read_as_color[:,:,0]+img_read_as_color[:,:,1]+img_read_as_color[:,:,2])/3
channel_sum = img_read_as_color[:,:,0]+img_read_as_color[:,:,1]+img_read_as_color[:,:,2]
plt.imshow(channel_avg_div_separately)
plt.title('channel_avg_div_separately')
plt.show()
plt.imshow(channel_avg_div_together)
plt.title('channel_avg_div_together')
plt.show()
plt.imshow(channel_sum)
plt.title('channel_sum')
plt.show()
Run Code Online (Sandbox Code Playgroud)
gray_pixel = 0.114 * blue_pixel + 0.299 * red_pixel + 0.587 * green_pixel
Run Code Online (Sandbox Code Playgroud)
文档中也提到了这一点。因此,预计 RGB2GRAY 和 BGR2GRAY 会给出不同的结果。
img_read_as_color[:,:,0]/3+img_read_as_color[:,:,1]/3+img_read_as_color[:,:,2]/3
Run Code Online (Sandbox Code Playgroud)
和
(img_read_as_color[:,:,0]+img_read_as_color[:,:,1]+img_read_as_color[:,:,2])/3
Run Code Online (Sandbox Code Playgroud)
回想一下,它cv2.imread返回一个 uint8 numpy 数组。因此,后一个操作(在除法之前将所有通道组合在一起)会导致溢出(实际上,在这种情况下,ipython3 给了我一个运行时警告)。在标记为channel_avg_div_together和 的图像中也可以看到类似溢出的伪影channel_sum。
小智 5
嗯,首先,转换不是简单的平均,更不用说线性变换了。计算公式为RGB[A] to Gray:Y\xe2\x86\x900.299\xe2\x8b\x85R+0.587\xe2\x8b\x85G+0.114\xe2\x8b\x85B(OpenCV Docs)
显然,无论使用 BGR 还是 RGB 作为输入,OpenCV 使用相同的公式来转换为灰度,但使用该公式时会保留通道顺序,因此转换时传递的错误顺序将导致错误的结果。
\n一个很好的例子是我最近看到的一篇论坛帖子,其中作者比较了 RGB 和 BGR 转换后的结果。右下角像素具有以下值。(图片来源为链接的帖子/作者)
\nCV_BGR2GRAY: Lower right corner: 0.1140 * 163 + 0.5870 * 182 + 0.2989 * 203 \xe2\x89\x88 186\n\nCV_RGB2GRAY: Lower right corner: 0.1140 * 203 + 0.5870 * 182 + 0.2989 * 163 \xe2\x89\x88 179\nRun Code Online (Sandbox Code Playgroud)\n所以tl;dr:如果传递的通道顺序错误,转换后的输出将会有所不同。
\n\n\n| 归档时间: |
|
| 查看次数: |
5173 次 |
| 最近记录: |