screwdriver/create/create.py

256 lines
12 KiB
Python
Raw Normal View History

2025-02-06 16:10:58 +08:00
import configparser
import math
import os
import sys
import numpy as np
import cv2
from PyQt5 import QtWidgets
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QHeaderView, QTableWidgetItem, QFileDialog
from Creat_Window import Ui_MainWindow
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self) # 創建主界面對象
self.setupUi(self)
self.database_create = Database_Create()
self.database_create.Created_Signal.connect(self.Created)
self.messages_Finish_count = 0
self.tableWidget.setColumnCount(3)
self.tableWidget.setRowCount(16)
self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.tableWidget.horizontalHeader().setSectionResizeMode(0, QHeaderView.Interactive)
self.comboBox_ClassNames.addItems(folder_name for folder_name in os.listdir(self.database_create.input_folder))
self.comboBox_IncreaseMultiplier.addItems([str(i) for i in range(1, 80)])
config = configparser.ConfigParser()
config.read('Creat_Config.ini')
self.label_InputFilePath.setText(config['FilePathInformation']['inputfilepath'])
self.label_OutputFilePath.setText(config['FilePathInformation']['outputfilepath'])
self.initTableWidget()
self.iniGuiEvent()
def iniGuiEvent(self):
self.comboBox_ClassNames.currentIndexChanged.connect(self.ValueChange_ClassNames)
self.comboBox_IncreaseMultiplier.currentIndexChanged.connect(self.ValueChange_IncreaseMultiplier)
self.pushButton.clicked.connect(self.Creating)
self.pushButton_ChangeInputFilePath.clicked.connect(self.ChangeFilePath)
self.pushButton_ChangeOutputFilePath.clicked.connect(self.ChangeFilePath)
def Creating(self):
self.database_create.start()
def Created(self, classname):
item = QTableWidgetItem(str(len(os.listdir(os.path.join(self.database_create.output_folder, classname)))))
self.tableWidget.setItem([cn for cn in self.database_create.ClassNameAndQuantity.keys()].index(classname.lower()), 2, item)
def initTableWidget(self):
self.tableWidget.clear()
row = 0
for key in self.database_create.Config_dic.keys():
# Write the value to the current (row, col) position in the TableWidget
item = QTableWidgetItem(key)
self.tableWidget.setItem(row, 0, item)
item = QTableWidgetItem(str(self.database_create.Config_dic[key]))
self.tableWidget.setItem(row, 1, item)
if self.database_create.OutputFileFolderAmountList == []:
item = QTableWidgetItem('None')
else:
item = QTableWidgetItem(str(self.database_create.OutputFileFolderAmountList[row]))
self.tableWidget.setItem(row, 2, item)
row += 1
def ValueChange_ClassNames(self):
self.comboBox_IncreaseMultiplier.setCurrentIndex(int(self.database_create.Config_dic[self.comboBox_ClassNames.currentText().lower()])-1)
def ValueChange_IncreaseMultiplier(self):
self.database_create.Config_dic[self.comboBox_ClassNames.currentText().lower()] = int(self.comboBox_IncreaseMultiplier.currentText())
self.initTableWidget()
def ChangeFilePath(self):
sender = self.sender() # Get the button that was clicked
name = sender.accessibleName() # Get the accessibleName property
print(f"Clicked button name: {name}")
dir = QFileDialog.getExistingDirectory(self, "Open Directory",
'./',
QFileDialog.ShowDirsOnly
| QFileDialog.DontResolveSymlinks)
if dir is not '':
config = configparser.ConfigParser()
config.read('Creat_Config.ini')
if name == 'In':
self.label_InputFilePath.setText(dir)
self.database_create.input_folder = dir
config.set('FilePathInformation', "inputfilepath", dir)
config.write(open('Creat_Config.ini', "r+")) # r+模式
elif name == 'Out':
self.label_OutputFilePath.setText(dir)
self.database_create.output_folder = dir
config.set('FilePathInformation', "outputfilepath", dir)
config.write(open('Creat_Config.ini', "r+")) # r+模式
else:
print('dir is None')
class Database_Create(QThread):
Created_Signal = pyqtSignal(str)
def __init__(self):
super().__init__()
self.input_folder = ''
self.output_folder = ''
self.ScaleROI_Data = []
# self.ReadScaleROI_Data()
self.Config_dic = {}
self.ClassNameAndQuantity = {}
self.OutputFileFolderAmountList = []
self.ReadINI()
self.GettingClassInformation()
self.Calculating()
self.readOutputFilefolderAmonut()
def Unsharpen(self, inputimage):
# USM锐化增强方法(Unsharpen Mask)
# 先对原图高斯模糊用原图减去系数x高斯模糊的图像
# 再把值Scale到0~255的RGB像素范围
# 优点:可以去除一些细小细节的干扰和噪声,比卷积更真实
# (原图像-w*高斯模糊)/1-ww表示权重0.1~0.9默认0.6
# sigma = 5、15、25
blur_img = cv2.GaussianBlur(inputimage, (0, 0), 5)
usm = cv2.addWeighted(inputimage, 1.5, blur_img, -0.5, 0)
# cv.addWeighted(图1,权重1, 图2, 权重2, gamma修正系数, dst可选参数, dtype可选参数)
h, w = inputimage.shape[:2]
result = np.zeros([h, w * 2], dtype=inputimage.dtype)
result[0:h, 0:w] = inputimage
result[0:h, w:2 * w] = usm
# cv.putText(图像名标题x坐标y坐标字体字的大小颜色字的粗细
return usm
def ReadScaleROI_Data(self):
with open(r"C:\Users\user\Desktop\ROI\Config\0_rotate_and_mirror.txt", 'r') as file:
lines = file.readlines()
for line in lines:
line_data = line.strip().split(' ')
if len(line_data) == 5: # 确保每行都有5个数据项
line_data[1] = int(float(line_data[1]) * 3400)
line_data[2] = int(float(line_data[2]) * 1852)
self.ScaleROI_Data.append(tuple(map(int, line_data[0:3])))
def ReadINI(self):
config = configparser.ConfigParser()
config.read('Creat_Config.ini')
self.input_folder = config['FilePathInformation']['inputfilepath']
self.output_folder = config['FilePathInformation']['outputfilepath']
def GettingClassInformation(self):
file_list = os.listdir(self.input_folder)
for className in file_list:
self.ClassNameAndQuantity[className.lower()] = len((os.listdir(os.path.join(self.input_folder, className))))
def Calculating(self):
for className in self.ClassNameAndQuantity.keys():
self.Config_dic[className] = 1 if round(1250/(self.ClassNameAndQuantity[className]*8))==0 else round(1250/(self.ClassNameAndQuantity[className]*8))
def WriteINI(self):
config = configparser.ConfigParser()
config['Multiple'] = {}
for key in self.Config_dic.keys():
config['Multiple'][key] = str(self.Config_dic[str(key).lower()])
with open('Creat_Config.ini', 'w') as f:
config.write(f)
def CaculateRoateAngle(self, forder_name):
value = self.Config_dic[forder_name.lower()]
print(f'int(value){int(value)}')
angle = 360 / int(value)
return angle
def run(self):
self.new_creat()
# self.creat()
def creat(self):
folder_counter = 0
for folder_name in os.listdir(self.output_folder):
folder_path = os.path.join(self.output_folder, folder_name)
Angle = self.CaculateRoateAngle(folder_name)
if os.path.isdir(folder_path):
output_subfolder = os.path.join(self.output_folder, folder_name)
os.makedirs(output_subfolder, exist_ok=True)
print(f"Reading images from folder: {folder_path}")
for file_name in os.listdir(folder_path):
file_path = os.path.join(folder_path, file_name)
if os.path.isfile(file_path) and file_name.endswith(('.jpg', '.png', '.jpeg')):
image = cv2.imread(file_path)
center = (image.shape[1] // 2, image.shape[0] // 2)
for angle in range(int(Angle), 360, int(Angle)):
print(int(angle))
rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0)
rotated_image = cv2.warpAffine(image, rotation_matrix, (image.shape[1], image.shape[0]))
resized_image = cv2.resize(rotated_image, (224, 224))
new_file_name = f"{folder_counter}_rotated_{angle}_{file_name}"
new_file_path = os.path.join(output_subfolder, new_file_name)
# if file_name == '12_Phillips_1' or file_name == '13_Phillips_2':
resized_image = self.Unsharpen(resized_image)
cv2.imwrite(new_file_path, resized_image)
print(f"Saved rotated image: {new_file_path}")
self.Created_Signal.emit(folder_name)
folder_counter += 1
# self.WriteINI()
print('end')
def new_creat(self):
folder_counter = 0
for folder_name in os.listdir(self.input_folder):
folder_path = os.path.join(self.input_folder, folder_name)
if os.path.isdir(folder_path):
output_subfolder = os.path.join(self.output_folder, folder_name)
os.makedirs(output_subfolder, exist_ok=True)
print(f"Reading images from folder: {folder_path}")
for file_name in os.listdir(folder_path):
file_path = os.path.join(folder_path, file_name)
if os.path.isfile(file_path) and file_name.endswith(('.jpg', '.png', '.jpeg')):
image = cv2.imread(file_path)
center = (image.shape[1] // 2, image.shape[0] // 2)
for angle in range(0, 360, 90):
rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0)
rotated_image = cv2.warpAffine(image, rotation_matrix, (image.shape[1], image.shape[0]))
resized_image = cv2.resize(rotated_image, (224, 224))
new_file_name = f"{folder_counter}_rotated_{angle}_{file_name}"
new_file_path = os.path.join(output_subfolder, new_file_name)
cv2.imwrite(new_file_path, resized_image)
new_file_name = f"{folder_counter}_rotated_{angle}_flipx_{file_name}"
new_file_path = os.path.join(output_subfolder, new_file_name)
cv2.imwrite(new_file_path, cv2.flip(resized_image, 0))
self.Created_Signal.emit(folder_name)
folder_counter += 1
# self.WriteINI()
print('end')
def readOutputFilefolderAmonut(self):
parent_folder = self.output_folder
# Initialize an empty list to store the folder names and file counts
file_counts = []
# Iterate through entries (files and folders) in the parent folder
if os.path.exists(parent_folder):
for entry in os.scandir(parent_folder):
if entry.is_dir():
folder_name = entry.name
# List all files in the child folder
files_in_child_folder = [f.name for f in os.scandir(entry.path) if f.is_file()]
# Get the count of files in the child folder and append it to the list
file_count = len(files_in_child_folder)
file_counts.append(file_count)
self.OutputFileFolderAmountList = file_counts
if __name__ == '__main__':
app = QApplication(sys.argv) # 固定的PyQt5程式都需要QApplication對象。sys.argv是命令列參數清單確保程式可以按兩下運行
MyWindow = MainWindow() # 初始化
MyWindow.show() # 將視窗控制項顯示在螢幕上
sys.exit(app.exec_()) # 程式運行sys.exit方法確保程式完整退出