如何将第一个处理图像(例如 Canny 过滤器)的输出作为另一个处理过滤器的输入?
Posted
技术标签:
【中文标题】如何将第一个处理图像(例如 Canny 过滤器)的输出作为另一个处理过滤器的输入?【英文标题】:How do I take the output of the first processed image(e.g., Canny Filter) as input to another process filter? 【发布时间】:2020-12-15 23:31:52 【问题描述】:如何将第一个处理后的图像(例如 Canny 过滤器)的输出作为另一个处理/过滤器(例如 Sobel 过滤器)的输入,而不是对原始图像应用任何过滤器?
在应用任何过滤器之前
应用过滤器后
每当我应用另一个进程时,它都会在原始图像上再次完成(不是第一个进程/过滤器的输出)。
代码:-
import sys
import numpy as np
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import cv2
class Ui_MainWindow(QMainWindow):
global img
def __init__(self):
super().__init__()
self.init_Main_Ui()
self.init_Menu_Ui()
def init_Main_Ui(self):
self.setObjectName("test")
self.setEnabled(True)
self.resize(1200, 700)
self.setMinimumSize(QtCore.QSize(500, 300))
self.setMaximumSize(QtCore.QSize(500, 300))
self.image_label = QLabel(self)
self.setCentralWidget(self.image_label)
self.show()
def init_Menu_Ui(self):
global img
menu_bar = self.menuBar()
menu_bar.setNativeMenuBar(False)
file_menu = menu_bar.addMenu('&File') # &가 alt+F 메뉴 단축키 지정
Exit_action = QAction('Exit', self)
Exit_action.setShortcut('Ctrl+Q')
Exit_action.triggered.connect(qApp.quit)
Open_action = QAction('open', self)
Open_action.setShortcut('Ctrl+O')
Open_action.triggered.connect(self.read_file)
file_menu.addAction(Open_action)
file_menu.addAction(Exit_action)
self.filter_menu = menu_bar.addMenu("&Filter")
self.filter_menu.setEnabled(False)
Sobel_action = QAction('Sobel filter', self)
Sobel_action.setShortcut('Alt+1')
Sobel_action.triggered.connect(
lambda: self.Sobel_filter(img)
)
Prewitt_action = QAction('Prewitt filter', self)
Prewitt_action.setShortcut('Alt+2')
Prewitt_action.triggered.connect(
lambda : self.Prewitt_filter(img)
)
Gaussian_action = QAction('Gaussian filter', self)
Gaussian_action.setShortcut('Alt+3')
Gaussian_action.triggered.connect(
lambda : self.Gaussian_filter(img)
)
Canny_action = QAction('Canny filter', self)
Canny_action.setShortcut('Alt+4')
Canny_action.triggered.connect(
lambda : self.Canny_filter(img)
)
LoG_action = QAction('LoG filter', self)
LoG_action.setShortcut('Alt+5')
LoG_action.triggered.connect(
lambda : self.LoG_filter(img)
)
self.setWindowTitle('Image Processing')
self.filter_menu.addAction(Sobel_action)
self.filter_menu.addAction(Prewitt_action)
self.filter_menu.addAction(Gaussian_action)
def read_file(self):
global img
file_name = QFileDialog.getOpenFileName(self)
if file_name[0] is not '':
img0 = cv2.imread(file_name[0])
img = cv2.cvtColor(img0, cv2.COLOR_BGR2RGB)
self.reshow_image(img)
print('aa')
self.filter_menu.setEnabled(True)
else:
print('please put img')
def save_image(self):
print("save")
def Sobel_filter(self, img):
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
sobel = img.copy()
height = np.size(img, 0)
width = np.size(img, 1)
for i in range(width):
for j in range(height):
sobel[j, i] = np.minimum(255, np.round(np.sqrt(sobelx[j, i] * sobelx[j, i] + sobely[j, i] * sobely[j, i])))
sobel = cv2.cvtColor(sobel, cv2.COLOR_GRAY2RGB)
cv2.imwrite("Sobel Filtered Image.png", sobel)
self.reshow_image(sobel)
def Prewitt_filter(self, img):
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
kernelx = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]])
kernely = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]])
img_prewittx = cv2.filter2D(img, -1, kernelx)
img_prewitty = cv2.filter2D(img, -1, kernely)
Prewitt = cv2.cvtColor(img_prewittx + img_prewitty, cv2.COLOR_GRAY2RGB)
self.reshow_image(Prewitt)
def Gaussian_filter(self, img):
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
img_smooth = cv2.GaussianBlur(img, (3, 3), 0)
img_smooth = cv2.cvtColor(img_smooth, cv2.COLOR_GRAY2RGB)
self.reshow_image(img_smooth)
def reshow_image(self, cv_img):
if cv_img is not None:
self.image_label.resize(cv_img.shape[1], cv_img.shape[0])
Q_img = QImage(cv_img.data, cv_img.shape[1], cv_img.shape[0], cv_img.shape[1] * 3, QImage.Format_RGB888)
self.image_label.setPixmap(QPixmap.fromImage(Q_img))
else:
print("Image load failed")
def exit(self):
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ui = Ui_MainWindow()
sys.exit(app.exec_())
【问题讨论】:
我不明白问题出在哪里。也许每个过滤器都应该将结果分配给变量 - 即。self.current_image
- 您将在下一个过滤器中使用它。
也许你应该学会使用self.
而不是global
【参考方案1】:
坦率地说,我不明白你为什么会遇到问题。
每个过滤器都应该将图像分配给全局/类变量,即。 self.current_img
def Gaussian_filter(self, img):
# ... code ...
self.current_img = img_smooth
self.reshow_image(self.current_img)
def Sobel_filter(self, img):
# ... code ...
self.current_img = sobel
self.reshow_image(self.current_img)
def Prewitt_filter(self, img):
# ... code ...
self.current_img = Prewitt
self.reshow_image(self.current_img)
每个过滤器都应该使用来自这个变量self.current_img
的图像
Canny_action.triggered.connect(
lambda : self.Canny_filter(self.current_img)
)
Sobel_action.triggered.connect(
lambda: self.Sobel_filter(self.current_img)
)
Prewitt_action.triggered.connect(
lambda : self.Prewitt_filter(self.current_img)
)
Gaussian_action.triggered.connect(
lambda : self.Gaussian_filter(self.current_img)
)
Canny_action.triggered.connect(
lambda : self.Canny_filter(self.current_img)
)
LoG_action.triggered.connect(
lambda : self.LoG_filter(self.current_img)
)
开始阅读时也是这样
if file_name[0] != '': # is not '':
img = cv2.imread(file_name[0])
self.current_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
self.original_img = self.current_img.copy()
self.reshow_image(self.current_img)
如果我想从原始图像开始,我还使用self.original_img
来保留原始图像。
编辑
使用类变量self.current_img
,您甚至可以直接在方法中使用它——无需作为参数发送。
Canny_action.triggered.connect(self.Canny_filter)
Sobel_action.triggered.connect(self.Sobel_filter)
Prewitt_action.triggered.connect(self.Prewitt_filter)
Gaussian_action.triggered.connect(self.Gaussian_filter)
Canny_action.triggered.connect(self.Canny_filter)
LoG_action.triggered.connect(self.LoG_filter)
def Gaussian_filter(self):
img = self.current_img
# ... code ...
self.current_img = img_smooth
self.reshow_image(self.current_img)
def Sobel_filter(self):
img = self.current_img
# ... code ...
self.current_img = sobel
self.reshow_image(self.current_img)
def Prewitt_filter(self):
img = self.current_img
# ... code ...
self.current_img = Prewitt
self.reshow_image(self.current_img)
顺便说一句:
def reset_to_original_image(self):
self.current_img = self.original_img.copy()
self.reshow_image(self.current_img)
顺便说一句:
您甚至可以创建包含所有图像历史记录的列表
def Sobel_filter(self):
self.history.append(self.current_img.copy())
img = self.current_img
# ... code ...
self.current_img = sobel
self.reshow_image(self.current_img)
编辑:
完整的工作代码。
过滤器作用于前一个过滤器的结果。
你还有Reset to original image
的功能。
所有图像都被记录在历史中,您可以使用Undo
函数返回到上一个图像。你甚至可以撤消Reset
。
import sys
import numpy as np
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import cv2
class Ui_MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.init_Main_Ui()
self.init_Menu_Ui()
self.current_img = None # default value at start
self.original_img = None # default value at start
self.history = []
def init_Main_Ui(self):
self.setObjectName("test")
self.setEnabled(True)
self.resize(1200, 700)
self.setMinimumSize(QtCore.QSize(500, 300))
self.setMaximumSize(QtCore.QSize(500, 300))
self.image_label = QLabel(self)
self.setCentralWidget(self.image_label)
self.show()
def init_Menu_Ui(self):
menu_bar = self.menuBar()
menu_bar.setNativeMenuBar(False)
file_menu = menu_bar.addMenu('&File') # &가 alt+F 메뉴 단축키 지정
Exit_action = QAction('Exit', self)
Exit_action.setShortcut('Ctrl+Q')
Exit_action.triggered.connect(qApp.quit)
Open_action = QAction('open', self)
Open_action.setShortcut('Ctrl+O')
Open_action.triggered.connect(self.read_file)
file_menu.addAction(Open_action)
file_menu.addAction(Exit_action)
self.filter_menu = menu_bar.addMenu("&Filter")
self.filter_menu.setEnabled(False)
Reset_action = QAction('Reset to original image', self)
Reset_action.setShortcut('Alt+0')
Reset_action.triggered.connect(self.reset_to_original_image)
Sobel_action = QAction('Sobel filter', self)
Sobel_action.setShortcut('Alt+1')
Sobel_action.triggered.connect(self.Sobel_filter)
Prewitt_action = QAction('Prewitt filter', self)
Prewitt_action.setShortcut('Alt+2')
Prewitt_action.triggered.connect(self.Prewitt_filter)
Gaussian_action = QAction('Gaussian filter', self)
Gaussian_action.setShortcut('Alt+3')
Gaussian_action.triggered.connect(self.Gaussian_filter)
Canny_action = QAction('Canny filter', self)
Canny_action.setShortcut('Alt+4')
Canny_action.triggered.connect(self.Canny_filter) # filter has to exist
LoG_action = QAction('LoG filter', self)
LoG_action.setShortcut('Alt+5')
LoG_action.triggered.connect(self.LoG_filter) # filter has to exist
Undo_action = QAction('Undo filter', self)
Undo_action.setShortcut('Alt+X')
Undo_action.triggered.connect(self.Undo_filter) # filter has to exist
self.setWindowTitle('Image Processing')
self.filter_menu.addAction(Reset_action)
self.filter_menu.addAction(Sobel_action)
self.filter_menu.addAction(Prewitt_action)
self.filter_menu.addAction(Gaussian_action)
self.filter_menu.addAction(Undo_action)
def read_file(self):
file_name = QFileDialog.getOpenFileName(self)
if file_name[0] != '': # is not '':
img = cv2.imread(file_name[0])
self.original_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
self.current_img = self.original_img.copy()
self.reshow_image(self.current_img)
self.filter_menu.setEnabled(True)
else:
print('please put img')
def save_image(self):
print("save")
def reset_to_original_image(self):
self.history.append(self.current_img.copy())
self.current_img = self.original_img.copy()
self.reshow_image(self.current_img)
def Sobel_filter(self):
self.history.append(self.current_img.copy())
img = self.current_img
cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
sobel = img.copy()
height = np.size(img, 0)
width = np.size(img, 1)
for i in range(width):
for j in range(height):
sobel[j, i] = np.minimum(255, np.round(np.sqrt(sobelx[j, i] * sobelx[j, i] + sobely[j, i] * sobely[j, i])))
sobel = cv2.cvtColor(sobel, cv2.COLOR_GRAY2RGB)
cv2.imwrite("Sobel Filtered Image.png", sobel)
self.current_img = sobel
self.reshow_image(self.current_img)
def Prewitt_filter(self):
self.history.append(self.current_img.copy())
img = self.current_img
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
kernelx = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]])
kernely = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]])
img_prewittx = cv2.filter2D(img, -1, kernelx)
img_prewitty = cv2.filter2D(img, -1, kernely)
Prewitt = cv2.cvtColor(img_prewittx + img_prewitty, cv2.COLOR_GRAY2RGB)
self.current_img = Prewitt
self.reshow_image(self.current_img)
def Gaussian_filter(self):
self.history.append(self.current_img.copy())
img = self.current_img
img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
img_smooth = cv2.GaussianBlur(img, (3, 3), 0)
img_smooth = cv2.cvtColor(img_smooth, cv2.COLOR_GRAY2RGB)
self.current_img = img_smooth
self.reshow_image(self.current_img)
def Canny_filter(self):
print("TODO: create Canny_filter")
#self.history.append(self.current_img.copy())
#img = self.current_img
# ... code ...
#self.current_img = img_smooth
#self.reshow_image(self.current_img)
def LoG_filter(self):
print("TODO: create LoG_filter")
#self.history.append(self.current_img.copy())
#img = self.current_img
# ... code ...
#self.current_img = img_smooth
#self.reshow_image(self.current_img)
def Undo_filter(self):
if self.history:
self.current_img = self.history.pop(-1)
self.reshow_image(self.current_img)
def reshow_image(self, cv_img):
if cv_img is not None:
self.image_label.resize(cv_img.shape[1], cv_img.shape[0])
Q_img = QImage(cv_img.data, cv_img.shape[1], cv_img.shape[0], cv_img.shape[1] * 3, QImage.Format_RGB888)
self.image_label.setPixmap(QPixmap.fromImage(Q_img))
else:
print("Image load failed")
def exit(self):
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ui = Ui_MainWindow()
sys.exit(app.exec_())
【讨论】:
非常感谢!你的回答很有帮助!以上是关于如何将第一个处理图像(例如 Canny 过滤器)的输出作为另一个处理过滤器的输入?的主要内容,如果未能解决你的问题,请参考以下文章
MATLAB中的Canny算子矩阵:如何实现/获取? (只是过滤器,没有边缘检测器)