天天看點

OpenCV-圖像通道轉換問題

OpenCV-MAT對象中使用plt.imshow(img[:,:,::-1])如何實作将第二軸反向?

系統平台:win10 x64

一、明确幾個概念:

1.OpenCV内部每個通道并沒有固定對應某種顔色,隻是在用imshow()、imread()、imwrite()等函數時,才将通道按照藍、綠、紅的順序進行輸入和輸出;

2.我們也可以使用matplotlib的imshow()繪制圖像,但是它要求圖像的三個通道的存儲順序為RGB;

即OpenCV讀進來的圖像,通道順序為BGR, 而matplotlib的順序為RGB,是以需要轉換

img = cv2.imread('./test1.jpg')    #BGR

>>>

from matplotlib import pyplot as plt

>>>

plt.imshow(img[:,:,::-1])     RGB

plt.show()      用matplotlib的imshow()顯示圖像

3.img圖像的shape和strides屬性:

如:

>>>img[:].shape

(100,300,3)  (或第1軸)為:圖像的水準尺寸(寬度)——列數,第2個(或第2軸)為:圖像的通道數

>>>img[:].strides

(900,3,1)    #每個通道的資料占用1個位元組,而一個像素點占用3個位元組,一行資料占用:300*3=900個位元組,是以,圖像在記憶體中是連續存儲的

注意:

  • Mat對象本身提供的很多屬性和方法并不符合python風格,是以PyOpenCV對Mat類進行了擴充,使得它能像NumPy數組一樣使用
  • Mat對象本身并不是數組,是以它沒有shape屬性,是以:>>>img.shape  #會報錯:AttributeError: 'Mat' object has no attribute 'shape'

4.python切片操作:

如:    #s[a:b:c]形式是對s在a和b之間以c為間隔取值,c可以為負,負值意味着反向取值

>>>s = 'bicyle'

>>>s[::3]

'bye'

>>>s[::-1]

'elycib'

>>>s[::-2]

'eccb'

二、說明:img[:,:,::-1]

中括号中有兩個逗号,四個冒号

[:,:,::-1]

第一個冒号——取遍圖像的所有行數

第二個冒号——取遍圖像的所有列數

第三個和第四個冒号——取遍圖像的所有通道數,-1是反向取值

附測試代碼及其他方法:
#coding=utf-8
 
#OpenCV讀進來的圖像,通道順序為BGR, 而matplotlib的順序為RGB,是以需要轉換
import cv2
import numpy as np
from matplotlib import pyplot as plt
 
 
img = cv2.imread('./test1.jpg')
B, G, R = cv2.split(img)
 
#BGR轉RGB,方法1
img_rgb1 = cv2.merge([R, G, B])
 
#BGR轉RGB,方法2
img_rgb2 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
 
#BGR轉RGB,方法3
img_rgb3 = img[:,:,::-1]
 
 
plt.figure('BGR_RGB')
 
#顯示opencv讀進來的img, 通道順序BGR
plt.subplot(3,3,1), plt.imshow(img)
#顯示B通道
plt.subplot(3,3,4), plt.imshow(B)
#顯示B通道
plt.subplot(3,3,5), plt.imshow(G)
#顯示B通道
plt.subplot(3,3,6), plt.imshow(R)
#顯示将BGR轉為RGB的圖像,3種方法
plt.subplot(3,3,7), plt.imshow(img_rgb1)
plt.subplot(3,3,8), plt.imshow(img_rgb2)
plt.subplot(3,3,9), plt.imshow(img_rgb3)

plt.show()