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方法確保程式完整退出
|