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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# -*- 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_())