Numpy to QImage क्रैशिंग

Aug 29 2020

निम्न कोड बटन पर क्लिक करने पर या कुछ क्लिक के बाद क्रैश हो जाता है जब संकेत धागे से उत्सर्जित होता है और मुख्य गुई में पकड़ा जाता है।

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QThread
import numpy as np
import time
from PyQt5.QtWidgets import QApplication, QDialog, QPushButton, QVBoxLayout


def convert_np_qimage(cv_img , width, height):
    h, w, ch = cv_img.shape
    bytes_per_line = ch * w
    qim = QtGui.QImage(cv_img.data, w, h, bytes_per_line, QtGui.QImage.Format_RGB888)
    print(qim.size())
    return qim

class VideoThread(QThread):
    change_qimage_signal = pyqtSignal(QImage)
    
    def __init__(self):
        super().__init__()

    def run(self):
        print("run")
        width = 1280
        height = 1280
        
        cv_img = np.zeros([height,width,3],dtype=np.uint8)
        cv_img.fill(255)
        print("image shape: ", cv_img.shape)

        qimg = convert_np_qimage(cv_img, width, height)
        self.change_qimage_signal.emit(qimg)
        print("emitted")

        
    def stop(self):
        self.wait()

import sys

class Dialog(QDialog):

    def __init__(self):
        super(Dialog, self).__init__()
        Dialog.resize(self, 640, 480)
        
        button=QPushButton("Click")
        button.clicked.connect(self.startThread)
        
        mainLayout = QVBoxLayout()
        mainLayout.addWidget(button)
        
        
        self.setLayout(mainLayout)
        self.setWindowTitle("QImage Example")
        
    def startThread(self):
        self.thread = VideoThread()
        self.thread.change_qimage_signal.connect(self.getPixmap)
        self.thread.start()      
        
    def getPixmap(self, qimg):
        print("got qimage")
        qpixmap = QPixmap.fromImage(qimg)
        

if __name__ == '__main__':
    app = QApplication(sys.argv)
    dialog = Dialog()
    sys.exit(dialog.exec_())

यदि ऊंचाई और चौड़ाई कम संख्या में सेट हैं, तो प्रोग्राम दुर्घटनाग्रस्त नहीं होता है। 3. प्रोग्राम भी क्रैश नहीं होता है यदि हम उत्सर्जन करने से पहले qimixmap में परिवर्तित हो जाते हैं और सिग्नल प्रकार को QPixmap में बदल देते हैं। कार्यक्रम मूल रूप से opencv का उपयोग करके वेब कैमरा से चित्र प्राप्त करने के लिए लिखा गया था। Opencv द्वारा बनाई गई खस्ता सरणी बड़ी छवि आकारों के लिए भी क्रैश होती है।

उपयोग किया गया OS Windows10 है, pyqt संस्करण 5.12.3 है

किसी भी विचार दुर्घटना का कारण क्या हो सकता है?

जवाब

1 eyllanesc Aug 29 2020 at 12:13

लिनक्स में PyQt5 5.15 के साथ मैं समस्या को पुन: उत्पन्न नहीं करता हूं, लेकिन यह त्रुटि आम है और इसलिए होती है क्योंकि "डेटा" पास करने से जानकारी की प्रतिलिपि नहीं बनती है, बल्कि डेटा साझा किया जाता है, इसलिए कुछ बिंदु पर cv_img और सभी संबद्ध ऑब्जेक्ट "सहित" नष्ट हो जाते हैं डेटा "इसलिए सिग्नल के माध्यम से इसे ट्रांसमिट करते हुए और इसे QLabel में सेट करने के बाद कि" डेटा "पढ़ा जाता है, लेकिन इसमें अब मेमोरी नहीं है। इस मामले में समाधान "डेटा" की प्रतिलिपि बनाना है:

qim = QtGui.QImage(
    cv_img.data.tobytes(), w, h, bytes_per_line, QtGui.QImage.Format_RGB888
)

या QImage की प्रतिलिपि बनाएँ।

return qim.copy()