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.

136 lines
5.7 KiB

# -*- coding: utf-8 -*-
import sys
import cv2
import math
from PyQt5.QtCore import QRect, QCoreApplication, QMetaObject, Qt
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QMainWindow, QApplication, QMenuBar, QWidget, QPushButton, QGraphicsView, QGraphicsScene, \
QFileDialog, QStatusBar, QMessageBox
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton_1 = QPushButton(self.centralwidget)
self.pushButton_1.setObjectName("pushButton_1")
self.pushButton_1.setGeometry(QRect(80, 470, 191, 71))
self.pushButton_2 = QPushButton(self.centralwidget)
self.pushButton_2.setObjectName("pushButton_2")
self.pushButton_2.setGeometry(QRect(300, 470, 201, 71))
self.pushButton_3 = QPushButton(self.centralwidget)
self.pushButton_3.setObjectName("pushButton_3")
self.pushButton_3.setGeometry(QRect(530, 470, 201, 71))
self.graphicsView = QGraphicsView(self.centralwidget)
self.graphicsView.setObjectName("graphicsView")
self.graphicsView.setGeometry(QRect(70, 60, 275, 330))
self.graphicsView_2 = QGraphicsView(self.centralwidget)
self.graphicsView_2.setObjectName("graphicsView_2")
self.graphicsView_2.setGeometry(QRect(450, 60, 280, 330))
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QMenuBar(MainWindow)
self.menubar.setObjectName("menubar")
self.menubar.setGeometry(QRect(0, 0, 800, 23))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", "MainWindow", None))
self.pushButton_2.setText(QCoreApplication.translate("MainWindow", "Apply Funny Mirror", None))
self.pushButton_1.setText(QCoreApplication.translate("MainWindow", "Select Image", None))
self.pushButton_3.setText(QCoreApplication.translate("MainWindow", "Save Image", None))
def enlarge_effect(img):
#获取图像的高度 h宽度 w和颜色通道数
h, w, n = img.shape
#计算图像的中心点坐标
cx = w / 2
cy = h / 2
#定义影响的区域
radius = min(h, w) // 2
r = int(radius / 2.0)
#创建原始图像的一个副本,在这个副本上应用效果
new_img = img.copy()
#用双重循环来遍历图像的每一个像素
for i in range(w):
for j in range(h):
tx = i - cx
ty = j - cy
distance = tx * tx + ty * ty
#判断当前像素是否在影响范围内
if distance < radius * radius:
#图像中心区域的像素进行重新映射,创建一种放大效果
x = int(int(tx / 2.0) * (math.sqrt(distance) / r) + cx)
y = int(int(ty / 2.0) * (math.sqrt(distance) / r) + cy)
if 0 <= x < w and 0 <= y < h: # 添加边界检查
new_img[j, i, 0] = img[y, x, 0]
new_img[j, i, 1] = img[y, x, 1]
new_img[j, i, 2] = img[y, x, 2]
return new_img
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)
self.pushButton_1.clicked.connect(self.select_image)
self.pushButton_2.clicked.connect(self.apply_effect)
self.pushButton_3.clicked.connect(self.save_image)
self.input_img = None
self.output_img = None
def select_image(self):
options = QFileDialog.Options()
fileName, _ = QFileDialog.getOpenFileName(self, "Select Image", "", "Image Files (*.png *.jpg *.bmp)", options=options)
if fileName:
self.input_img = cv2.imread(fileName)
if self.input_img is None:
print("Error: Unable to read image file")
return
self.show_image(self.input_img, self.graphicsView)
def apply_effect(self):
if self.input_img is None:
return
self.output_img = enlarge_effect(self.input_img)
self.show_image(self.output_img, self.graphicsView_2)
def show_image(self, img, view):
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
h, w, ch = img_rgb.shape
bytes_per_line = ch * w
qimg = QImage(img_rgb.data, w, h, bytes_per_line, QImage.Format_RGB888)
pixmap = QPixmap.fromImage(qimg)
scene = QGraphicsScene()
scene.addPixmap(pixmap)
view.setScene(scene)
view.fitInView(scene.itemsBoundingRect(), Qt.KeepAspectRatio) # 修正了参数名称
def save_image(self):
if self.output_img is not None:
options = QFileDialog.Options()
options |= QFileDialog.ShowDirsOnly
file_name, _ = QFileDialog.getSaveFileName(self, "保存图片", "", "Images (*.png *.xpm *.jpg);;All Files (*)", options=options)
if file_name:
cv2.imwrite(file_name, self.output_img)
else:
QMessageBox.warning(self, "Warning", "没有转换后的图片可保存")
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())