python - 如何将第一个处理过的图像(例如 Canny 过滤器)的输出作为另一个处理过滤器的输入?
问题描述
如何将第一个处理过的图像(例如 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_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_())
推荐阅读
- excel - VBA 暗淡对象错误
- linkedin - Linkedin 资产 complete_multipartUpload api 抛出 401
- python - 如何从保存的 Dynet 模型中读回“随机种子”
- google-api - 从 Google 分析核心报告 API 中提取不同的值
- react-native-android - 反应本机按钮中的阴影
- scala - 从 spark 写入 hadoop 的最佳实践
- bash - 在bash中将前100k文件夹从一个目录复制到另一个目录的最快方法是什么
- apache - mod_brotli 和 apache 2.4.33 的编译问题
- android - ndk 套接字在 snapdragon 835 上不起作用
- maven - 我在 Android Studio 中出现 gradle 同步错误,“找不到参数 [com.github.dcendents:android-maven-gradle-plugin:2.0] 的方法 calsspath()”