☞ ░ 前往老猿Python博文目錄 ░
一、引言
在《PyQt轉換顯示Python-OpenCV圖像實現圖形化界面的視頻播放》介紹了實現在OpenCV和PyQt之間轉換並傳遞圖像實現在PyQt上播放視頻圖像的功能。其中的關鍵函數如下:
def cvImgtoQtImg(cvImg): #定義opencv圖像轉PyQt圖像的函數
QtImgBuf = cv2.cvtColor(cvImg, cv2.COLOR_BGR2BGRA)
QtImg = QtGui.QImage(QtImgBuf.data, QtImgBuf.shape[1], QtImgBuf.shape[0], QtGui.QImage.Format_RGB32)
return QtImg
但在使用該函數將一系列圖像轉換並用PyQt顯示時,發現部分時候存在變形或花屏。下圖爲截取的原圖樣例:
下圖是部分效果圖以及老猿測試時改變轉換類型時轉換後展示的效果圖:
相關圖形處理後的結果並不非常固定。
二、問題分析結論
針對上面的問題,老猿參考相關資料,並反覆測試和分析,最後得到如下結論:
1、OpenCV的圖像確實是BGR類型,包括VideoCapture和imread讀取圖像都是,而PyQt都是RGB類型,二者需要轉換,而上面函數中的轉換並不是完成BGR到RGB的轉換,而是BGR到BGRA的轉換,所以這種處理會導致圖像顏色發生變化;
2、OpenCV彩色圖像到PyQt彩色圖像,需要變換到四通道圖像RGBA格式才能完全不變形的顯示圖像,這兒的原理老猿還沒弄清楚,但測試效果就是這樣;
3、QImage對象構建時,圖像的類型不應該使用Format_RGB32,而應該選擇Format_RGB888,這二者是有區別的,關於這點請參考下面介紹的參考博文。
三、優化後的代碼
考慮灰度圖像的支持,該函數完善後的代碼如下:
def cvImgtoQtImg(cvImg,isConvertToGray=False): # 定義opencv圖像轉PyQt圖像的函數
if isConvertToGray:
QtImgBuf = cv2.cvtColor(cvImg, cv2.COLOR_BGR2GRAY)
QtImg = QtGui.QImage(QtImgBuf.data, QtImgBuf.shape[1], QtImgBuf.shape[0], QtGui.QImage.Format_Grayscale8)
else:
QtImgBuf = cv2.cvtColor(cvImg, cv2.COLOR_BGR2RGBA)
QtImg = QtGui.QImage(QtImgBuf.data, QtImgBuf.shape[1], QtImgBuf.shape[0], QtGui.QImage.Format_RGBA8888 )
return QtImg
這樣優化以後,所有OpenCV的圖像都能完整的在PyQt中使用,沒有任何變形。
參考博文:
感謝CSDN博主"草帽小子說編程"的《QImage圖像格式解讀》,爲本文相關測試提供了關鍵的幫助。
關於老猿的付費專欄
老猿的付費專欄《使用PyQt開發圖形界面Python應用》專門介紹基於Python的PyQt圖形界面開發基礎教程,付費專欄《moviepy音視頻開發專欄》詳細介紹moviepy音視頻剪輯合成處理的類相關方法及使用相關方法進行相關剪輯合成場景的處理,兩個專欄加起來只需要19.9元,都適合有一定Python基礎但無相關專利知識的小白讀者學習。這2個收費專欄都有對應免費專欄,只是收費專欄的文章介紹更具體、內容更深入、案例更多。
付費專欄文章目錄:《moviepy音視頻開發專欄文章目錄》、《使用PyQt開發圖形界面Python應用專欄目錄》。
關於Moviepy音視頻開發的內容,請大家參考《Python音視頻剪輯庫MoviePy1.0.3中文教程導覽及可執行工具下載》的導覽式介紹。
對於缺乏Python基礎的同仁,可以通過老猿的免費專欄《專欄:Python基礎教程目錄》從零開始學習Python。
如果有興趣也願意支持老猿的讀者,歡迎購買付費專欄。