1. 程式人生 > >Python - QImage轉OpenCV處理的資料結構及相反轉換

Python - QImage轉OpenCV處理的資料結構及相反轉換

軟體環境: Python3.6 / Python2.7   IDE: PYZO    傳送門: http://www.pyzo.org/       

需要安裝的Python庫: numpy cv2 PyQt5 ,安裝方法如下

pip install numpy   

pip install opencv-python
pip install PyQt5

個人推薦直接安裝Anaconda 3,  Anaconda3已內建numpy與PyQt5,只需執行 pip install opencv-pyhton即可

鑑於需要閱讀本文的人應該都知道QImage和cv2,直接上程式碼,覺得有用的話,不妨點贊,讓我樂呵樂呵

cv_image = cv2.imread("圖片路徑")  #此語句會返回一個opencv的圖片物件cv_image, 將image轉換為QImage的方法如下

def CV2QImage(cv_image):
    
    width = cv_image.shape[1] #獲取圖片寬度
    height = cv_image.shape[0]  #獲取圖片高度
    
    pixmap = QPixmap(width, height) #根據已知的高度和寬度新建一個空的QPixmap,
    qimg = pixmap.toImage()  #將pximap轉換為QImage型別的qimg
    
    #迴圈讀取cv_image的每個畫素的r,g,b值,構成qRgb物件,再設定為qimg內指定位置的畫素
    for row in range(0, height):
        for col in range(0,width):
            r = cv_image[row,col,0]
            g = cv_image[row,col,1]
            b = cv_image[row,col,2]
            
            pix = qRgb(r, g, b)
            qimg.setPixel(col, row, pix)
    
    return qimg #轉換完成,返回

將QImage物件轉換為cv2可以直接處理的圖象,方法如下

def QImage2CV(qimg):
    
    tmp = qimg
    
    #使用numpy建立空的圖象
    cv_image = numpy.zeros((tmp.height(), tmp.width(), 3), dtype=numpy.uint8)
    
    for row in range(0, tmp.height()):
        for col in range(0,tmp.width()):
            r = qRed(tmp.pixel(col, row))
            g = qGreen(tmp.pixel(col, row))
            b = qBlue(tmp.pixel(col, row))
            cv_image[row,col,0] = r
            cv_image[row,col,1] = g
            cv_image[row,col,2] = b
    
    return cv_image

下面是測試上述兩個函式的完整測試例程

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import numpy as np
import cv2


def QImage2CV(qimg):
    
    tmp = qimg
    
    #使用numpy建立空的圖象
    cv_image = np.zeros((tmp.height(), tmp.width(), 3), dtype=np.uint8)
    
    for row in range(0, tmp.height()):
        for col in range(0,tmp.width()):
            r = qRed(tmp.pixel(col, row))
            g = qGreen(tmp.pixel(col, row))
            b = qBlue(tmp.pixel(col, row))
            cv_image[row,col,0] = r
            cv_image[row,col,1] = g
            cv_image[row,col,2] = b
    
    return cv_image
    
def CV2QImage(cv_image):
    
    width = cv_image.shape[1] #獲取圖片寬度
    height = cv_image.shape[0]  #獲取圖片高度
    
    pixmap = QPixmap(width, height) #根據已知的高度和寬度新建一個空的QPixmap,
    qimg = pixmap.toImage()  #將pximap轉換為QImage型別的qimg
    
    #迴圈讀取cv_image的每個畫素的r,g,b值,構成qRgb物件,再設定為qimg內指定位置的畫素
    for row in range(0, height):
        for col in range(0,width):
            r = cv_image[row,col,0]
            g = cv_image[row,col,1]
            b = cv_image[row,col,2]
            
            pix = qRgb(r, g, b)
            qimg.setPixel(col, row, pix)
    
    return qimg #轉換完成,返回

path = "E:\\Temp\\"  #存放測試圖片的路徑,請自行定義

qpixmap = QPixmap(500, 300)
qpixmap.fill(Qt.green)

painter = QPainter()
painter.begin(qpixmap)
painter.setPen(Qt.black)
painter.setBrush(Qt.white)
painter.drawEllipse(QRect(50, 100, 50, 100))
painter.drawLine(0,0,200,100)
painter.end()

qimg = qpixmap.toImage()
qimg.save(path + "qimg-origin.bmp")
image = QImage2CV(qimg)

start_point = (0, 0)
end_point = (250, 300)
line_width = 4
line_type = 8
color = (255,255,0)
cv2.line(image, start_point, end_point, color, line_width, line_type)

qimg_2 = CV2QImage(image)
qimg_2.save(path + "qimg-from-cv_img.bmp")

cv2.imshow("line", image)
cv2.waitKey()
cv2.destroyAllWindows()