I have the problem that I cannot connect the implementation between two buttons. After I pressed the "Grayscale" button and got the grayscale image, I pressed the "Canny" button but the user interface suddenly closed.
I don't know what's wrong in my code.
def getImage(self):global fnamefname = QFileDialog.getOpenFileName(self, 'Open file', 'C:\\Users\binil-ping\Desktop\CODE',"Image Files (*.jpg *.gif *.bmp *.png)")pixmap = QPixmap(fname[0])self.label.setPixmap(QPixmap(pixmap))self.resize(pixmap.width(), pixmap.height())def Grayscale(self):global edgesedges = cv2.imread(fname[0], 0)edges = cv2.GaussianBlur(edges, (5, 5), 0)height, width = edges.shape[:2]ret,edges = cv2.threshold(edges,150,255,cv2.THRESH_BINARY)kernel = np.ones((5,5),np.uint8)edges = cv2.morphologyEx(edges, cv2.MORPH_OPEN, kernel)edges = cv2.morphologyEx(edges, cv2.MORPH_OPEN, kernel)edges = QImage(edges, width, height, QImage.Format_Grayscale8)pixmap = QPixmap.fromImage(edges)self.label.setPixmap(pixmap)self.resize(pixmap.width(), pixmap.height())def Canny(self):edges2 = cv2.imread(edges[0],-1)edges2 = cv2.Canny(edges2,180,200)edges2 = QImage(edges2, width, height, QImage.Format_Grayscale8)pixmap = QPixmap.fromImage(edges2)self.label.setPixmap(pixmap)self.resize(pixmap.width(), pixmap.height())
There are a lot of problems with your code (including the fact that you didn't provide a minimal, reproducible example), some of them explaining the crash or possibly leading to another one (I've marked them with [*]):
- as already pointed out, avoid using globals whenever possible (which is almost always), use class attributes instead;
- you are continuously overwriting those globals, making everything very confusing also for debugging; in fact you're using
edges
for both a numpy array and a QImage;
- [*] you are trying to
cv2.imread(edges[0],-1)
, but not only imread expects a string, but, as a result of the previous point, at that point edges
is even a QImage;
- [*] some variables are not declared in the scope of the function (width/height in the Canny function);
- you should really avoid using capitalized names for functions and variables, as they are usually only for class names and builtin constants;
- there are some issues in the conversion back to QImage, I suppose that's due to the various transformations you're applying to to the array (some of them also seem unnecessary) that are not very friendly with the Format_Grayscale8 format, perhaps you should better investigate about that;
Here's a possible improvement over your code. I'm adding the widget creation parts, as it was missing in the original example.
class ShowImage(QWidget):def __init__(self):QWidget.__init__(self)layout = QVBoxLayout(self)self.label = QLabel()layout.addWidget(self.label)self.getImageBtn = QPushButton()layout.addWidget(self.getImageBtn)self.getImageBtn.clicked.connect(self.getImage)self.grayBtn = QPushButton('gray')layout.addWidget(self.grayBtn)self.grayBtn.clicked.connect(self.grayScale)self.cannyBtn = QPushButton('canny')layout.addWidget(self.cannyBtn)self.cannyBtn.clicked.connect(self.canny)self.fileName = Noneself.edges = Nonedef getImage(self):fname = QFileDialog.getOpenFileName(self, 'Open file', 'C:\\Users\binil-ping\Desktop\CODE',"Image Files (*.jpg *.gif *.bmp *.png)")if fname[0]:self.fileName = fname[0]pixmap = QPixmap(self.fileName)self.label.setPixmap(pixmap)def grayScale(self):if not self.fileName:returnedges = cv2.imread(self.fileName, 0)edges = cv2.GaussianBlur(edges, (5, 5), 0)ret,edges = cv2.threshold(edges, 150, 255, cv2.THRESH_BINARY)kernel = np.ones((5, 5), np.uint8)edges = cv2.morphologyEx(edges, cv2.MORPH_OPEN, kernel)edges = cv2.morphologyEx(edges, cv2.MORPH_OPEN, kernel)self.edges = edgesheight, width = edges.shape[:2]image = QImage(edges, width, height, QImage.Format_Grayscale8)pixmap = QPixmap.fromImage(image)self.label.setPixmap(pixmap)def canny(self):if self.edges is None:returnedges2 = cv2.Canny(self.edges, 180, 200)height, width = edges2.shape[:2]edges2 = QImage(edges2, width, height, QImage.Format_Grayscale8)pixmap = QPixmap.fromImage(edges2)self.label.setPixmap(pixmap)