Python/pyqt5/CODE/ROIpractice/main.py

146 lines
6.6 KiB
Python
Raw Normal View History

2024-06-25 22:02:02 +08:00
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_())