Skip to content

Commit 695014a

Browse files
author
yura496
committed
First version
0 parents  commit 695014a

7 files changed

Lines changed: 591 additions & 0 deletions

File tree

main.py

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
import sys, cv2, shutil, time, os
2+
import numpy as np
3+
from skimage.metrics import structural_similarity as compare_ssim
4+
from PyQt5.QtWidgets import *
5+
from PyQt5 import uic,QtCore
6+
7+
form_class = uic.loadUiType("./src/UI.ui")[0]
8+
class MCS(QtCore.QThread,QtCore.QObject):
9+
result = QtCore.pyqtSignal(str)
10+
label = QtCore.pyqtSignal(str)
11+
pbar_value = QtCore.pyqtSignal(float)
12+
go_stop = QtCore.pyqtSignal(bool)
13+
def __init__(self,p1,p2,p3,st,c1,c2,parent=None):
14+
super(MCS,self).__init__(parent)
15+
self.p1 = p1
16+
self.p2 = p2
17+
self.p3 = p3
18+
self.st = st
19+
self.c1 = c1
20+
self.c2 = c2
21+
self.thread_type = ''
22+
self.working = True
23+
self.go_stop.emit(True)
24+
def monster_search (self,sPath):
25+
source = cv2.imread(sPath,cv2.IMREAD_COLOR) # 검사 대상
26+
if source.shape[1]==1366:
27+
source = source[268:345,369:959] # 1366 * 768 에서 출력되는 위치 자르기
28+
elif source.shape[1]==800:
29+
source = source[100:177,86:676]
30+
elif source.shape[1]==1024:
31+
source = source[268:345,198:788]
32+
elif source.shape[1]==1280:
33+
source = source[220:297,326:916]
34+
elif source.shape[1]==1920:
35+
source = source[424:501,646:1236]
36+
else:
37+
print("지원되지 않는 형식!")
38+
return 0
39+
40+
target = np.load('src//target.npy') # 탐색 목표 이미지
41+
mask = target[:,:,-1] #타겟의 알파 마스크 출력
42+
tmp,mask_r=cv2.threshold(mask,254,255,cv2.THRESH_BINARY) # tmp는 사용하지 않음, 유사 부울린 마스크(mask_r) 생성
43+
target = cv2.cvtColor(target,cv2.COLOR_RGBA2RGB)
44+
45+
w,h=source.shape[:2]
46+
47+
tgt = np.zeros((w,h,3),np.uint8)
48+
cv2.copyTo(target,mask_r,tgt)
49+
50+
src = np.zeros((w,h,3),np.uint8)
51+
cv2.copyTo(source,mask_r,src)
52+
53+
score , tmp = compare_ssim(src, tgt, full=True,multichannel=True)
54+
# full=True: 이미지 전체에 대해서 구조비교를 수행한다.
55+
return score * 100
56+
def file_list(self,root_dir,listbool):
57+
img_list = []
58+
img_name = ['.jpg', '.jpeg', '.JPG', '.PNG', '.png']
59+
if listbool == 2:
60+
for (root, dirs, files) in os.walk(root_dir):
61+
if len(files) > 0:
62+
for file_name in files:
63+
if file_name.startswith('Maple_A') and os.path.splitext(file_name)[1] in img_name:
64+
img_path = root + "\\" + file_name
65+
img_list.append(img_path)
66+
else :
67+
for files in os.listdir(root_dir):
68+
if files.startswith('Maple_A') and '.'+files.split('.')[-1] in img_name:
69+
img_path = root_dir + "\\" + files
70+
img_list.append(img_path)
71+
return(img_list)
72+
def run(self):
73+
timestr = time.strftime("%y-%m-%d_%H-%M-%S ")
74+
if self.thread_type =='class' and self.working:
75+
not_mon_log = "\n\n몬컬이 아닌 캡쳐 목록:"
76+
mon_log = "\n\n몬컬 캡처 목록:"
77+
cap_list = self.file_list(self.p1,self.c1)
78+
all_n = len(cap_list)
79+
i = 0
80+
for source in cap_list:
81+
filename = source.split('\\')[-1]
82+
score= self.monster_search(source)
83+
if score < self.st :
84+
shutil.move(source,self.p2+'\\'+filename)
85+
not_mon_log = not_mon_log+'\n'+filename+':'+f"{score:.1f}"+'%'
86+
else :
87+
shutil.move(source,self.p3+'\\'+filename)
88+
mon_log = mon_log+'\n'+filename+':'+f"{score:.1f}"+'%'
89+
i=i+1
90+
self.label.emit(f'{i}'+'/'+f'{all_n}')
91+
self.result.emit(filename+':'+f"{score:.1f}"+'%')
92+
self.pbar_value.emit((i+1)/all_n)
93+
if self.c2 :
94+
f = open(f"{os.getcwd()}\\log-{timestr}.txt",'w',encoding='UTF-8')
95+
f.write("시작시간: "+timestr+not_mon_log+mon_log)
96+
f.close()
97+
self.go_stop.emit(False)
98+
elif self.thread_type =='log' and self.working:
99+
not_mon_log = "\n\n몬컬이 아닌 캡쳐 목록:"
100+
mon_log = "\n\n몬컬 캡처 목록:"
101+
cap_list = self.file_list(self.p1,self.c1)
102+
all_n = len(cap_list)
103+
i = 0
104+
for source in cap_list:
105+
filename = source.split('\\')[-1]
106+
score= self.monster_search(source)
107+
if score < self.st :
108+
not_mon_log = not_mon_log+'\n'+filename+':'+f"{score:.1f}"+'%'
109+
else :
110+
mon_log = mon_log+'\n'+filename+':'+f"{score:.1f}"+'%'
111+
i=i+1
112+
self.label.emit(f'{i}'+'/'+f'{all_n}')
113+
self.result.emit(filename+':'+f"{score:.1f}"+'%')
114+
self.pbar_value.emit((i+1)/all_n)
115+
if self.c2 :
116+
f = open(f"{os.getcwd()}\\log-{timestr}.txt",'w',encoding='UTF-8')
117+
f.write("시작시간: "+timestr+not_mon_log+mon_log)
118+
f.close()
119+
self.go_stop.emit(False)
120+
else:
121+
self.terminate()
122+
self.quit()
123+
class MyWindow(QMainWindow, form_class):
124+
path_signal = QtCore.pyqtSignal(str)
125+
def __init__(self):
126+
super().__init__()
127+
self.setupUi(self)
128+
129+
self.pushButton.clicked.connect(self.getFilepath1)
130+
self.pushButton_2.clicked.connect(self.getFilepath2)
131+
self.pushButton_3.clicked.connect(self.getFilepath3)
132+
133+
self.pushButton_4.clicked.connect(self.classifying)
134+
self.pushButton_5.clicked.connect(self.logonly)
135+
def getFilepath1(self):
136+
path_name = QFileDialog.getExistingDirectory(self)
137+
self.lineEdit.setText(path_name)
138+
if path_name :
139+
self.pushButton_5.setEnabled(True)
140+
if self.lineEdit_3.text() and self.lineEdit_2.text() and self.lineEdit.text():
141+
self.pushButton_4.setEnabled(True)
142+
def getFilepath2(self):
143+
path_name = QFileDialog.getExistingDirectory(self)
144+
self.lineEdit_2.setText(path_name)
145+
if self.lineEdit_3.text() and self.lineEdit_2.text() and self.lineEdit.text():
146+
self.pushButton_4.setEnabled(True)
147+
def getFilepath3(self):
148+
path_name = QFileDialog.getExistingDirectory(self)
149+
self.lineEdit_3.setText(path_name)
150+
if self.lineEdit_3.text() and self.lineEdit_2.text() and self.lineEdit.text():
151+
self.pushButton_4.setEnabled(True)
152+
def classifying(self):
153+
154+
self.progressBar.setEnabled(True)
155+
self.textEdit.setText("")
156+
157+
check1 = self.checkBox.checkState()
158+
check2 = self.checkBox_2.checkState()
159+
p1 = self.lineEdit.text()
160+
p2 = self.lineEdit_2.text()
161+
p3 = self.lineEdit_3.text()
162+
st = self.spinBox.value()
163+
self.switch_widgets(True)
164+
self.th = MCS(p1,p2,p3,st,check1,check2,parent=self)
165+
self.th.result.connect(self.setResultBox)
166+
self.th.pbar_value.connect(self.pBarUpdate)
167+
self.th.label.connect(self.label5update)
168+
self.th.go_stop.connect(self.thread_stop)
169+
self.th.start()
170+
self.th.thread_type = 'class'
171+
def logonly(self):
172+
self.progressBar.setEnabled(True)
173+
self.textEdit.setText("")
174+
self.switch_widgets(True)
175+
176+
check1 = self.checkBox.checkState()
177+
check2 = self.checkBox_2.checkState()
178+
p1 = self.lineEdit.text()
179+
st = self.spinBox.value()
180+
181+
self.th = MCS(p1,'','',st,check1,check2,parent=self)
182+
self.th.result.connect(self.setResultBox)
183+
self.th.pbar_value.connect(self.pBarUpdate)
184+
self.th.label.connect(self.label5update)
185+
self.th.go_stop.connect(self.thread_stop)
186+
self.th.start()
187+
self.th.thread_type = 'log'
188+
def setResultBox(self, result):
189+
self.textEdit.append(result)
190+
def switch_widgets(self,onoff):
191+
if onoff:
192+
self.pushButton.setDisabled(True)
193+
self.pushButton_2.setDisabled(True)
194+
self.pushButton_3.setDisabled(True)
195+
self.pushButton_4.setDisabled(True)
196+
self.pushButton_5.setDisabled(True)
197+
self.checkBox.setDisabled(True)
198+
self.checkBox_2.setDisabled(True)
199+
self.spinBox.setDisabled(True)
200+
else:
201+
self.pushButton.setEnabled(True)
202+
self.pushButton_2.setEnabled(True)
203+
self.pushButton_3.setEnabled(True)
204+
if self.lineEdit_3.text() and self.lineEdit_2.text() and self.lineEdit.text():
205+
self.pushButton_4.setEnabled(True)
206+
self.pushButton_5.setEnabled(True)
207+
self.checkBox.setEnabled(True)
208+
self.checkBox_2.setEnabled(True)
209+
self.spinBox.setEnabled(True)
210+
@QtCore.pyqtSlot(float)
211+
def pBarUpdate(self,val):
212+
self.progressBar.setValue(val*100)
213+
@QtCore.pyqtSlot(str)
214+
def label5update(self,val):
215+
self.label_5.setText(val)
216+
@QtCore.pyqtSlot(bool)
217+
def thread_stop(self,val):
218+
if val == False:
219+
self.th.terminate()
220+
self.th.working = False
221+
self.switch_widgets(False)
222+
if __name__ == "__main__":
223+
app = QApplication(sys.argv)
224+
myWindow = MyWindow()
225+
myWindow.show()
226+
app.exec_()

main.spec

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# -*- mode: python ; coding: utf-8 -*-
2+
3+
4+
block_cipher = pyi_crypto.PyiBlockCipher(key='hi!mynameisyura')
5+
6+
7+
a = Analysis(['main.py'],
8+
pathex=['D:\\PROJECT\\Python\\MonsterCollectionCapturePicker\\venv\\lib\\site-packages\\cv2'],
9+
binaries=[],
10+
datas=[],
11+
hiddenimports=[],
12+
hookspath=[],
13+
hooksconfig={},
14+
runtime_hooks=[],
15+
excludes=[],
16+
win_no_prefer_redirects=False,
17+
win_private_assemblies=False,
18+
cipher=block_cipher,
19+
noarchive=False)
20+
pyz = PYZ(a.pure, a.zipped_data,
21+
cipher=block_cipher)
22+
23+
exe = EXE(pyz,
24+
a.scripts,
25+
a.binaries,
26+
a.zipfiles,
27+
a.datas,
28+
[],
29+
name='main',
30+
debug=False,
31+
bootloader_ignore_signals=False,
32+
strip=False,
33+
upx=True,
34+
upx_exclude=[],
35+
runtime_tmpdir=None,
36+
console=False,
37+
disable_windowed_traceback=False,
38+
target_arch=None,
39+
codesign_identity=None,
40+
entitlements_file=None , icon='src\\favicon.ico')

requirements.txt

1.26 KB
Binary file not shown.

0 commit comments

Comments
 (0)