You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
6.6 KiB
193 lines
6.6 KiB
import sys
|
|
from PyQt6.QtCore import Qt
|
|
from PyQt6.QtWidgets import *
|
|
import PyQt6.QtGui as QtGui
|
|
from PyQt6.QtGui import QColor, QAction, QPixmap, QPalette
|
|
from pathlib import Path
|
|
import cv2
|
|
import numpy as np
|
|
from Photo import Photo
|
|
from functools import partial
|
|
|
|
|
|
class Judge:
|
|
def __init__(self, newWindow: QDialog, confirm, cancel):
|
|
button1 = QPushButton('Confirm', newWindow)
|
|
button1.clicked.connect(confirm)
|
|
button2 = QPushButton('Cancel', newWindow)
|
|
button2.clicked.connect(cancel)
|
|
hbox = QHBoxLayout()
|
|
hbox.addWidget(button1)
|
|
hbox.addWidget(button2)
|
|
self.hbox = hbox
|
|
|
|
|
|
class Menu:
|
|
def __init__(self, menu: QMenu):
|
|
self.menu = menu
|
|
|
|
def addFun(self, name, p, lam):
|
|
action = QAction(name, p)
|
|
action.triggered.connect(lam)
|
|
self.menu.addAction(action)
|
|
|
|
|
|
def changeValue(sld, label):
|
|
text = f'ratio: {sld.value()}'
|
|
label.setText(text)
|
|
|
|
|
|
class PhotoProcessor(QMainWindow):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
self.labelImage = None
|
|
self.initUI()
|
|
|
|
def initUI(self):
|
|
self.labelImage = QLabel(self)
|
|
self.initMenu()
|
|
self.showMaximized()
|
|
|
|
def initMenu(self):
|
|
self.statusBar()
|
|
|
|
menuBar = self.menuBar()
|
|
fileMenu = menuBar.addMenu('File')
|
|
editMenu = menuBar.addMenu('Edit')
|
|
self.fileMenu = Menu(fileMenu)
|
|
self.editMenu = Menu(editMenu)
|
|
self.initFileMenu()
|
|
self.initEditMenu()
|
|
|
|
def initEditMenu(self):
|
|
self.editMenu.addFun('Rotate', self, lambda: self.noAsk(Photo.rotate))
|
|
self.editMenu.addFun('Vertical Mirror', self, lambda: self.noAsk(Photo.vertical_mirror))
|
|
self.editMenu.addFun('Horizontal Mirror', self, lambda: self.noAsk(Photo.horizontal_mirror))
|
|
self.editMenu.addFun('Resize', self, lambda: self.ask('ratio', 1, 500, 100, Photo.resize))
|
|
# wait for brightness
|
|
self.editMenu.addFun('Lightning', self, lambda: self.ask('value', -100, 100, 0, Photo.lighting))
|
|
# crash
|
|
self.editMenu.addFun('Contrast', self, lambda: self.ask('value', -100, 100, 0, Photo.contrast))
|
|
self.editMenu.addFun('Hue', self, lambda: self.ask('value', 0, 180, 0, Photo.hue))
|
|
|
|
blurMenu = self.editMenu.menu.addMenu('Blur')
|
|
self.blurMenu = Menu(blurMenu)
|
|
self.blurMenu.addFun('Blur', self, lambda: self.ask('value', 0, 20, 0, Photo.blur))
|
|
self.blurMenu.addFun('Median_Blur', self, lambda: self.ask('value', 0, 20, 0, Photo.median_blur))
|
|
self.blurMenu.addFun('gaussian_blur', self, lambda: self.ask('value', 0, 20, 0, Photo.gaussian_blur))
|
|
|
|
self.editMenu.addFun('Gray', self, lambda: self.noAsk(Photo.to_gray))
|
|
self.editMenu.addFun('Invert', self, lambda: self.noAsk(Photo.invert))
|
|
|
|
binaryMenu = self.editMenu.menu.addMenu('Binary')
|
|
self.binaryMenu = Menu(binaryMenu)
|
|
self.binaryMenu.addFun('Binary', self, lambda: self.ask('threshold', 0, 255, 127, Photo.to_binary))
|
|
self.binaryMenu.addFun('Binary_ostu', self, lambda: self.noAsk(Photo.to_binary_ostu))
|
|
self.binaryMenu.addFun('Binary_adaptive', self, lambda: self.noAsk(Photo.to_binary_adaptive))
|
|
|
|
self.editMenu.addFun('Sharpen', self, lambda: self.ask('value', 0, 20, 0, Photo.sharpen))
|
|
self.editMenu.addFun('Open', self, lambda: self.noAsk(Photo.open))
|
|
self.editMenu.addFun('Close', self, lambda: self.noAsk(Photo.close))
|
|
self.editMenu.addFun('Scale', self, lambda: self.noAsk(Photo.scale))
|
|
self.editMenu.addFun('Equalize', self, lambda: self.noAsk(Photo.equalizeHist))
|
|
self.editMenu.addFun('DetectAntigen', self, lambda: self.noAsk(Photo.detectQRcode))
|
|
|
|
def noAsk(self, func):
|
|
func(self.Image)
|
|
self.display_image()
|
|
|
|
def initFileMenu(self):
|
|
self.fileMenu.addFun('Open Image', self, self.openImage)
|
|
self.fileMenu.addFun('Save Image', self, self.saveImage)
|
|
self.fileMenu.addFun('Original Image', self, lambda: self.noAsk(Photo.origin))
|
|
|
|
def saveImage(self):
|
|
home_dir = str(Path.home())
|
|
filepath = QFileDialog.getSaveFileName(self, 'Save File', home_dir, 'Image files(*.jpg)')
|
|
if filepath[0]:
|
|
cv2.imwrite(filepath[0], self.Image.img)
|
|
|
|
def openImage(self):
|
|
home_dir = str(Path.home())
|
|
filepath = QFileDialog.getOpenFileName(self, 'Open Image', home_dir, "Image files(*.jpg *.png)")
|
|
|
|
if filepath[0]:
|
|
self.Image = Photo(filepath[0])
|
|
self.display_image()
|
|
|
|
def display_image(self):
|
|
shrink = cv2.cvtColor(self.Image.img, cv2.COLOR_BGR2RGB)
|
|
|
|
qt_img = QtGui.QImage(shrink.data,
|
|
shrink.shape[1],
|
|
shrink.shape[0],
|
|
shrink.shape[1] * 3,
|
|
QtGui.QImage.Format.Format_RGB888)
|
|
|
|
w, h = qt_img.width(), qt_img.height()
|
|
f1 = 1.0 * self.width() / w
|
|
f2 = 1.0 * self.height() / h
|
|
factor = min([f1, f2])
|
|
width = int(w * factor)
|
|
height = int(h * factor)
|
|
|
|
self.labelImage.setPixmap(QPixmap.fromImage(qt_img).scaled(width, height))
|
|
|
|
self.labelImage.resize(width, height)
|
|
|
|
# self.image_resize()
|
|
|
|
def image_resize(self):
|
|
w, h = self.labelImage.width(), self.labelImage.height()
|
|
f1 = 1.0 * self.width() / w
|
|
f2 = 1.0 * self.height() / h
|
|
factor = min([f1, f2])
|
|
width = int(w * factor)
|
|
height = int(h * factor)
|
|
self.labelImage.resize(width, height)
|
|
|
|
def cancel(self):
|
|
self.sender().parent().close()
|
|
|
|
def ask(self, text_, min_value, max_value, init, func):
|
|
newWindow = QDialog()
|
|
text = text_ + f': {init}'
|
|
|
|
vbox = QVBoxLayout()
|
|
label = QLabel(text, newWindow)
|
|
sld = QSlider(Qt.Orientation.Horizontal, newWindow)
|
|
sld.setMaximum(max_value)
|
|
sld.setMinimum(min_value)
|
|
sld.setTickPosition(QSlider.TickPosition.TicksAbove)
|
|
sld.setSliderPosition(init)
|
|
sld.setFocusPolicy(Qt.FocusPolicy.NoFocus)
|
|
sld.setGeometry(30, 40, 200, 30)
|
|
sld.valueChanged[int].connect(lambda: changeValue(sld, label))
|
|
|
|
judge = Judge(newWindow, lambda: self.setValue(sld, func), self.cancel)
|
|
|
|
vbox.addWidget(label)
|
|
vbox.addWidget(sld)
|
|
vbox.addLayout(judge.hbox)
|
|
|
|
newWindow.setLayout(vbox)
|
|
newWindow.show()
|
|
newWindow.exec()
|
|
|
|
def setValue(self, sld, fun):
|
|
a = self.sender()
|
|
b = a.parent()
|
|
b.close()
|
|
fun(self.Image, sld.value())
|
|
self.display_image()
|
|
|
|
|
|
def run():
|
|
app = QApplication(sys.argv)
|
|
pp = PhotoProcessor()
|
|
sys.exit(app.exec())
|
|
|
|
|
|
run()
|