【matplotlib + opencv】關於opencv和matplotlib繪製圖像時,出現色差色偏的問題探討,思考,解決。(深度學習數據包plt.imshow繪製的圖像底色偏綠藍偏黃)

一、圖像紅變藍,藍變紅的問題

(1)原因分析

  • 用cv2.imread()讀取數據,用plt.imshow()展示數據會出現紅變藍,藍變紅的問題。
  • 原因:cv2.imread() 讀取圖像格式爲b,g,r(這是由於以前流行bgr格式的圖像顯示方式,今年才流行rgb格式,opencv的這個格式是歷史遺留問題)而 plt.imshow()顯示按照 rgb次序。因此會出現色偏,應該使用
  • RGB 和 BGR 的轉換可以直接使用 cvt = org[:,:,::-1] 來實現,前兩個 : 表示第一第二維不變,::-1表示將第三維倒序排列。

(2)代碼及結果展示

1)錯誤代碼

import cv2
import matplotlib.pyplot as plt

image = cv2.imread('1.jpg')
# image = image[:, :, ::-1]
print(image.shape)
plt.imshow(image)
# 關閉x,y軸刻度
plt.xticks([])
plt.yticks([])
# 關閉座標軸
plt.axis('off')
plt.show()

2)錯誤結果

  • 左邊爲原圖,右邊爲plt.imshow()顯示的圖片,可以發現紅變藍,藍變紅的問題

3)正確代碼

  • RGB 和 BGR 的轉換可以直接使用 cvt = org[:,:,::-1] 來實現,前兩個 : 表示第一第二維不變,::-1表示將第三維倒序排列。
import cv2
import matplotlib.pyplot as plt

image = cv2.imread('1.jpg')
# 修改的地方,bgr→rgb
image = image[:, :, ::-1]
# 或image = image[:,:,[2,1,0]]
print(image.shape)
plt.imshow(image)
# 關閉x,y軸刻度
plt.xticks([])
plt.yticks([])
# 關閉座標軸
plt.axis('off')
plt.show()

二、深度學習數據包plt.imshow繪製圖像偏藍黃色

(1)原因分析

  • 色偏問題原因:plt.imshow()在繪製2維圖像時,0(最小值)顯示深藍色,1(最大值)顯示黃色,其他數值顯示由藍到黃的過度顏色,所以圖像畫出來是藍黃相間的。

1)原理解釋代碼

# coding=utf-8
from matplotlib import pyplot as plt

X = [[0.1, 0.2, 0.3],
     [0.4, 0.5, 0.6],
     [0.7, 0.8, 0.9]]
plt.imshow(X)
plt.colorbar()
# # 關閉x,y軸刻度
# plt.xticks([])
# plt.yticks([])
# # 關閉座標軸
# plt.axis('off')
plt.show()

2)結果

在這裏插入圖片描述

(2)實際繪圖分析與解決

1)問題代碼示例

import matplotlib.pyplot as plt
import numpy as np
import torchvision
import torchvision.transforms as transforms
from IPython import display

np.set_printoptions(threshold=100000000)

mnist_train = torchvision.datasets.FashionMNIST(root='./data', train=True, download=True,
                                                transform=transforms.ToTensor())
mnist_test = torchvision.datasets.FashionMNIST(root='./data', train=False, download=True,
                                               transform=transforms.ToTensor())


def use_svg_display():
    """Use svg format to display plot in jupyter"""
    display.set_matplotlib_formats('svg')


# 本函數已保存在d2lzh包中方便以後使用
def get_fashion_mnist_labels(labels):
    text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
                   'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
    return [text_labels[int(i)] for i in labels]


# 本函數已保存在d2lzh包中方便以後使用
def show_fashion_mnist(images, labels):
    use_svg_display()
    # 這裏的_表示我們忽略(不使用)的變量
    _, figs = plt.subplots(1, len(images), figsize=(12, 12))
    for f, img, lbl in zip(figs, images, labels):
        # np.squeeze將(1,28,28)→(28,28)
        f.imshow(np.squeeze(img.numpy()))
        f.set_title(lbl)
        f.axes.get_xaxis().set_visible(False)
        f.axes.get_yaxis().set_visible(False)
    plt.show()


# 完成了torch.utils.data.DataLoader的功能
X, y = [], []
for i in range(10):
    X.append(mnist_train[i][0])
    y.append(mnist_train[i][1])
show_fashion_mnist(X, get_fashion_mnist_labels(y))

2)問題結果

在這裏插入圖片描述

3)期望代碼示例

  • 繪製出黑白圖像方法:將三個相同的(28,28, 1)的圖像升維爲(28,28, 3)的圖像,然後繪製出來,就可以發現是正常的黑白圖像了。
import matplotlib.pyplot as plt
import numpy as np
import torchvision
import torchvision.transforms as transforms
from IPython import display

np.set_printoptions(threshold=100000000)

mnist_train = torchvision.datasets.FashionMNIST(root='./data', train=True, download=True,
                                                transform=transforms.ToTensor())
mnist_test = torchvision.datasets.FashionMNIST(root='./data', train=False, download=True,
                                               transform=transforms.ToTensor())


def use_svg_display():
    """Use svg format to display plot in jupyter"""
    display.set_matplotlib_formats('svg')


# 本函數已保存在d2lzh包中方便以後使用
def get_fashion_mnist_labels(labels):
    text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
                   'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
    return [text_labels[int(i)] for i in labels]


# 本函數已保存在d2lzh包中方便以後使用
def show_fashion_mnist(images, labels):
    use_svg_display()
    # 這裏的_表示我們忽略(不使用)的變量
    _, figs = plt.subplots(1, len(images), figsize=(12, 12))
    for f, img, lbl in zip(figs, images, labels):
        img = np.squeeze(img).numpy()
        # (3, 28, 28)
        image = np.array([img, img, img])
        # (3, 28, 28) → (28, 28, 3)
        f.imshow(np.transpose(image, (1, 2, 0)))
        f.set_title(lbl)
        f.axes.get_xaxis().set_visible(False)
        f.axes.get_yaxis().set_visible(False)
    plt.show()


# 完成了torch.utils.data.DataLoader的功能
X, y = [], []
for i in range(10):
    X.append(mnist_train[i][0])
    y.append(mnist_train[i][1])
show_fashion_mnist(X, get_fashion_mnist_labels(y))

4)期望結果

  • 最後終於得到了想要的黑白圖像啦!
    在這裏插入圖片描述

三、參考

【小記】RGB圖像轉換爲BGR-詳細講解了如何手動將RGB圖像轉換爲BGR圖像
python將兩個二維array疊加成三維array的實現方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章