146 lines
6.6 KiB
Python
146 lines
6.6 KiB
Python
|
import cv2
|
|||
|
import sys, time, os
|
|||
|
import numpy as np
|
|||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
|||
|
from PyQt5.QtGui import QColor,QPen,QPainter,QPixmap,QImage,QPainterPath,QPolygonF
|
|||
|
from test1 import Ui_MainWindow
|
|||
|
from PyQt5.QtCore import QDate,QTime,Qt, QRect, QPoint, pyqtSignal
|
|||
|
from PyQt5.QtWidgets import QApplication, QFileDialog, QLabel,QMainWindow, QWidget, QPushButton
|
|||
|
|
|||
|
|
|||
|
def original(img): # 原圖
|
|||
|
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # QT顏色顯示轉換
|
|||
|
Ny , Nx , _ =img.shape
|
|||
|
img = QtGui.QImage(img.data, Nx, Ny, Nx*3 , QtGui.QImage.Format_RGB888) # 須改格式
|
|||
|
return img
|
|||
|
|
|||
|
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||
|
def __init__(self, parent=None): #按鍵設定
|
|||
|
super(MainWindow, self).__init__(parent)
|
|||
|
self.setupUi(self)
|
|||
|
self.PhotoOpen_Btn_1.clicked.connect(self.openfile1) # 按鍵open1
|
|||
|
self.ROI_Btn.clicked.connect(self.showNewWindow) # 按鍵open1
|
|||
|
self.roi_rect = QRect(100, 100, 50, 50) # ROI 的固定座標與大小 (x,y,Rx,Ry) xy為原始圖片的座標位置,RxRy為以座標位置延伸的長寬
|
|||
|
|
|||
|
|
|||
|
# 開啟資料夾 並選擇圖片
|
|||
|
def openfile1(self):
|
|||
|
filename, _ = QFileDialog.getOpenFileName(self, 'Open Image')
|
|||
|
self.img = cv2.imread(str(filename),cv2.IMREAD_GRAYSCALE)
|
|||
|
self.img_original = original(self.img) #original 為轉UI顯示格式
|
|||
|
self.img_view1=self.img_original
|
|||
|
self.photoshow1.setPixmap(QtGui.QPixmap.fromImage(self.img_view1))
|
|||
|
#選取ROI 開啟新視窗
|
|||
|
def showNewWindow(self):
|
|||
|
self.nw = newWindow(self.img_view1) # 連接新視窗
|
|||
|
self.nw.positionsChanged.connect(self.handlePositionsChanged) # 連接信號
|
|||
|
self.nw.imageSaved.connect(self.receiveImage)# 連接信號
|
|||
|
self.nw.show() # 顯示新視窗
|
|||
|
x = self.nw.pos().x() # 取得新視窗目前 x 座標
|
|||
|
y = self.nw.pos().y() # 取得新視窗目前 y 座標
|
|||
|
self.nw.move(x+20, y) # 移動新視窗位置
|
|||
|
|
|||
|
def handlePositionsChanged(self, positions):
|
|||
|
# 這個方法會在 newWindow 實例發出 positionsChanged 信號時被調用
|
|||
|
# positions 參數包含了 newWindow 實例發出信號時傳遞的數據
|
|||
|
self.clicked_positions = positions
|
|||
|
print(self.clicked_positions)
|
|||
|
|
|||
|
def receiveImage(self, image):
|
|||
|
self.photoshow2.setPixmap(QtGui.QPixmap.fromImage(image))
|
|||
|
print(image)
|
|||
|
pass
|
|||
|
class newWindow(QtWidgets.QMainWindow):
|
|||
|
positionsChanged = pyqtSignal(list)
|
|||
|
imageSaved = QtCore.pyqtSignal(QtGui.QImage)
|
|||
|
def __init__(self,img_view1):
|
|||
|
super(newWindow, self).__init__()
|
|||
|
self.img_view1 = img_view1 #將主畫面讀到的圖檔拉來子畫面
|
|||
|
self.ui() #子畫面初始化元件
|
|||
|
self.newWindowsize_x =self.img_view1.width()
|
|||
|
self.newWindowsize_y =self.img_view1.height()
|
|||
|
self.setWindowTitle('newWindow')
|
|||
|
self.setFixedSize(800, 800)
|
|||
|
self.setMouseTracking(True)
|
|||
|
self.shownewWindowlabel1()
|
|||
|
self.clicked_positions = []
|
|||
|
|
|||
|
def ui(self):
|
|||
|
self.newWindowlabel1 = QtWidgets.QLabel(self)
|
|||
|
self.newWindowlabel1.setText('newWindowlabel1')
|
|||
|
self.newWindowlabel1.setGeometry(0, 0, 800, 800)
|
|||
|
self.newWindowlabel1.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft) # 設置文本對齊在左上角
|
|||
|
# self.newWindowlabel1.setScaledContents(True)
|
|||
|
self.newWindowlabel2 = QtWidgets.QLabel(self)
|
|||
|
self.newWindowlabel2.setText('newWindowlabel2')
|
|||
|
self.newWindowlabel2.setGeometry(0, 0, 200, 100)
|
|||
|
self.newWindowlabel2.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft) # 設置文本對齊在左上角
|
|||
|
def shownewWindowlabel1(self):
|
|||
|
self.img_pixmap = QtGui.QPixmap.fromImage(self.img_view1)
|
|||
|
|
|||
|
def paintEvent(self,event):
|
|||
|
super().paintEvent(event)
|
|||
|
qpainter = QPainter(self)
|
|||
|
qpainter.drawPixmap(self.rect(), self.img_pixmap) # 在窗口上繪製圖片,保持原始尺寸
|
|||
|
qpainter.setPen(QPen(QColor('#ff0000'), 5))
|
|||
|
for pos in self.clicked_positions:
|
|||
|
x, y = pos
|
|||
|
qpainter.drawPoint(x, y)
|
|||
|
|
|||
|
if len(self.clicked_positions) == 4:
|
|||
|
# 將最後一個點和第一個點連線
|
|||
|
for i in range(len(self.clicked_positions)):
|
|||
|
x1, y1 = self.clicked_positions[i]
|
|||
|
x2, y2 = self.clicked_positions[(i + 1) % len(self.clicked_positions)]
|
|||
|
qpainter.drawLine(x1, y1, x2, y2)
|
|||
|
qpainter.end()
|
|||
|
self.cropImage()
|
|||
|
self.close()
|
|||
|
|
|||
|
def cropImage(self):
|
|||
|
per_x = self.img_pixmap.size().width() / self.width()
|
|||
|
per_y = self.img_pixmap.size().height() / self.height()
|
|||
|
x_values = [pos[0] for pos in self.clicked_positions]
|
|||
|
y_values = [pos[1] for pos in self.clicked_positions]
|
|||
|
self.min_x = int(min(x_values)*per_x)
|
|||
|
self.max_x = int(max(x_values)*per_x)
|
|||
|
self.min_y = int(min(y_values)*per_y)
|
|||
|
self.max_y = int(max(y_values)*per_y)
|
|||
|
qimage = self.img_pixmap.toImage()
|
|||
|
cropped_qimage = qimage.copy(self.min_x, self.min_y, self.max_x - self.min_x, self.max_y - self.min_y)
|
|||
|
self.cropped_pixmap = QPixmap.fromImage(cropped_qimage)
|
|||
|
self.cropped_pixmap.save(r"D:\python_code\photo\cropped_image.jpg") # 儲存裁剪後的圖像
|
|||
|
def mousePressEvent(self, event):
|
|||
|
if event.button() == 1:
|
|||
|
x = event.x()
|
|||
|
y = event.y()
|
|||
|
self.clicked_positions.append((x, y))
|
|||
|
print(self.clicked_positions)
|
|||
|
self.newWindowlabel2.setText(f'{x}, {y}') # 透過 QLabel 顯示滑鼠座標
|
|||
|
self.update()
|
|||
|
|
|||
|
def savePaintedPixmap(self):
|
|||
|
# 创建新的 QPixmap 对象,并在其上绘制原始图片和红点
|
|||
|
center_x = self.img_pixmap.width() // 2
|
|||
|
center_y = self.img_pixmap.height()// 2
|
|||
|
painted_pixmap = QtGui.QPixmap(self.img_pixmap.size())
|
|||
|
painter = QtGui.QPainter(painted_pixmap)
|
|||
|
painted_pixmap.fill(QtCore.Qt.black)
|
|||
|
# painter.drawPixmap(self.cropped_pixmap.width(),self.cropped_pixmap.height(), self.cropped_pixmap)
|
|||
|
painter.drawPixmap(center_x,center_y, self.cropped_pixmap)
|
|||
|
painter.end()
|
|||
|
|
|||
|
# 将 QPixmap 转换为 QImage 并发送
|
|||
|
painted_image = painted_pixmap.toImage()
|
|||
|
self.imageSaved.emit(painted_image)
|
|||
|
|
|||
|
def closeEvent(self, event):
|
|||
|
self.savePaintedPixmap()
|
|||
|
self.positionsChanged.emit(self.clicked_positions)
|
|||
|
|
|||
|
if __name__=='__main__':
|
|||
|
app = QtWidgets.QApplication(sys.argv)
|
|||
|
win = MainWindow()
|
|||
|
win.show()
|
|||
|
sys.exit(app.exec_())
|