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 fname
fname = 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 edges
edges = 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 [*]):
edges
for both a numpy array and a QImage;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; 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 = None
self.edges = None
def 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:
return
edges = 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 = edges
height, 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:
return
edges2 = 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)
Rule #1: Don't use globals.
Now on to the real answer.
PyQt has this really, really bad, annoying habit of just crashing if you have an uncaught exception in your code. That makes it hard to debug. Personally, I use a decorator around slots when debugging, which print my exception before PyQt can kill the application.
import logging
from functools import wraps
logger = logging.getLogger(__name__)
# ...lots of other code...
def debugFunc(*errors):
def decorator(func):
@wraps(func)
def runner(*args, **kwargs):
try:
return func(*args, **kwargs)
except errors as err:
logger.debug(f"Function {func.__name__} raised a {err.__class__.__name__}, which was ignored.",
exc_info=True)
except Exception as err:
logger.critical(f"{err.__class__.__name__} - {err}", exc_info=True)
return runner
return decorator
While debugging, this allows me to ignore certain errors, and sends all others to the logging
system. If you don't use it yourself and aren't willing to start using it, you can instead import traceback
and use it's functions, instead of my calls to my logger
object.
Just use this function as the innermost decorator, like this:
@debugFunc()
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())[enter image description here][1]
While I'm not familiar enough with cv2 to say for sure, I think your problem may be cv2.Canny. It doesn't look like the naming of other cv2 functions, and may cause an AttributeError if I'm right.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.