256 lines
12 KiB
Python
256 lines
12 KiB
Python
|
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-w);w表示权重(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方法確保程式完整退出
|