class EliteOCR(QMainWindow, Ui_MainWindow): def __init__(self, app): QMainWindow.__init__(self) #QMainWindow.__init__(self, None, Qt.FramelessWindowHint) self.setupUi(self) self.app = app self.settings = Settings(self) self.resizeElements() self.darkstyle = self.genDarkStyle() self.def_style = """ QWidget { font-size: 10pt; font-family: Consolas} QLineEdit { font-size: 13pt; font-family: Consolas} """ if self.settings["theme"] == "dark": self.dark_theme = True self.style = self.darkstyle else: self.dark_theme = False self.style = self.def_style self.app.setStyleSheet(self.style) self.appversion = appversion self.setupTable() self.export = Export(self) self.actionPublic_Mode.setChecked(self.settings["public_mode"]) self.factor.setValue(self.settings["zoom_factor"]) self.ocr_all_set = False self.color_image = None self.preview_image = None self.current_result = None self.newupd = None self.zoom = False self.minres = 0 self.busyDialog = None self.fields = [self.name, self.sell, self.buy, self.demand_num, self.demand, self.supply_num, self.supply] self.canvases = [self.name_img, self.sell_img, self.buy_img, self.demand_img, self.demand_text_img, self.supply_img, self.supply_text_img] #setup buttons self.add_button.clicked.connect(self.addFiles) self.remove_button.clicked.connect(self.removeFile) self.remove_all_button.clicked.connect(self.removeAllFiles) self.add_all_button.clicked.connect(self.addAllScreenshots) self.save_button.clicked.connect(self.addItemToTable) self.skip_button.clicked.connect(self.nextLine) self.continue_button.clicked.connect(self.continueOCR) self.ocr_button.clicked.connect(self.performOCR) self.ocr_all.clicked.connect(self.runOCRAll) self.export_button.clicked.connect(self.export.exportToFile) self.bpc_button.clicked.connect(self.export.bpcExport) self.eddn_button.clicked.connect(self.export.eddnExport) self.clear_table.clicked.connect(self.clearTable) self.zoom_button.clicked.connect(self.drawOCRPreview) QObject.connect(self.actionHelp, SIGNAL('triggered()'), self.openHelp) QObject.connect(self.actionUpdate, SIGNAL('triggered()'), self.openUpdate) QObject.connect(self.actionAbout, SIGNAL('triggered()'), self.About) QObject.connect(self.actionOpen, SIGNAL('triggered()'), self.addFiles) QObject.connect(self.actionPreferences, SIGNAL('triggered()'), self.openSettings) QObject.connect(self.actionPublic_Mode, SIGNAL('triggered()'), self.toggleMode) QObject.connect(self.actionCommodity_Editor, SIGNAL('triggered()'), self.openEditor) self.error_close = False #set up required items for nn self.training_image_dir = unicode(self.settings.app_path.decode('windows-1252'))+os.sep+u"nn_training_images"+os.sep self.loadPlugins() self.restorePos() self.eddnthread = EDDNExport(self) QObject.connect(self.eddnthread, SIGNAL('finished(QString)'), self.export.eddnFinished) QObject.connect(self.eddnthread, SIGNAL('update(int,int)'), self.export.eddnUpdate) self.thread = Worker() self.connect(self.thread, SIGNAL("output(QString, QString)"), self.showUpdateAvailable) self.thread.check(self.appversion) if not self.settings.reg.contains('info_accepted'): self.infoDialog = InfoDialog() self.infoDialog.exec_() else: if not self.settings['info_accepted']: self.infoDialog = InfoDialog() self.infoDialog.exec_() self.checkAppConfigXML() def checkAppConfigXML(self): path = unicode(self.settings['log_dir']).encode('windows-1252')+"\\..\\AppConfig.xml" if isfile(path): file = codecs.open(path, 'r', "utf-8") file_content = file.read() file.close() start = file_content.find("<Network") end = file_content.find("</Network>") position = file_content.lower().find('verboselogging="1"', start, end) if position == -1: msg = _translate("EliteOCR","You don't have \"Verbose Logging\" enabled in your AppConfig.xml. It is necessary for automatic system name recognition. Do you want EliteOCR to enable it for you?", None) reply = QMessageBox.question(self, 'Change File', msg, _translate("EliteOCR","Yes", None), _translate("EliteOCR","No", None)) if reply == 0: file = codecs.open(unicode(self.settings['log_dir']).encode('windows-1252')+"\\..\\AppConfig_backup.xml", 'w', "utf-8") file.write(file_content) file.close() newfile = file_content[:start+8] + '\n VerboseLogging="1"' + file_content[start+8:] file = codecs.open(path, 'w', "utf-8") file.write(newfile) file.close() QMessageBox.information(self,"Restart the Game", "Please restart the game to apply the change in AppConfig.xml") else: return def resizeElements(self): fields = [self.system_name, self.station_name, self.name, self.sell, self.buy, self.demand_num, self.demand, self.supply_num, self.supply, self.label_12, self.file_label, self.system_not_found] for field in fields: field.setMinimumSize(QSize(0, self.settings['input_size'])) field.setMaximumSize(QSize(16777215, self.settings['input_size'])) canvases = [self.station_name_img, self.name_img, self.sell_img, self.buy_img, self.demand_img, self.demand_text_img, self.supply_img, self.supply_text_img] for canvas in canvases: canvas.setMinimumSize(QSize(0, self.settings['snippet_size'])) canvas.setMaximumSize(QSize(16777215, self.settings['snippet_size'])) def genDarkStyle(self): style = """ QWidget {{ background-color: #000; font-size: 10pt; font-family: Consolas}} QLabel {{ color: {0};}} QCheckBox {{ color: {0}; }} QPushButton {{color: {2}; background-color: #000; border: 1px solid {3}; min-height: 13px; padding: 2px;}} QToolButton {{color: {2}; background-color: #000; border: 1px solid {3}; min-height: 12px; padding: 2px;}} QPushButton[enabled="false"]{{color: #555; border: 1px solid #555;}} QToolButton[enabled="false"]{{color: #555; border: 1px solid #555;}} QStatusBar {{ background-color: #000; color: {0};}} QMenuBar {{ background-color: #000; color: {0};}} QMenuBar::item {{ background-color: #000; color: {0};}} QMenuBar::item:selected {{ background-color: #888; color: {0};}} QMenu {{ background-color: #000; color: {0};}} QMenu::item {{ background-color: #000; color: {0};}} QMenu::item:selected {{ background-color: #888; color: {0};}} QListWidget {{ background-color: #000; min-width: 150px}} QFrame[frameShape="4"] {{ background-color: #888; }} QFrame[frameShape="5"] {{ background-color: #888; }} QGraphicsView {{ background-color: #000; border: 1px solid {4}}} QTableWidget {{ background-color: #000; color: {0}; border: 1px solid {4}}} QLineEdit {{ background-color: #000; border: 1px solid {4}; color: {1}; font-size: 13pt; font-family: Consolas}} QComboBox {{ background-color: #000; border: 1px solid {4}; color: {1};}} QComboBox:editable {{color: {1}; font-size: 11pt}} QComboBox::down-arrow {{ image: url(:/ico/arrow.png); }} QComboBox::drop-down:editable {{color: {1};}} QHeaderView::section {{ background-color: #000; color: {0}; border: 1px solid {4}; padding: 2px; }} QTableView QTableCornerButton::section {{ background: #000;}} QSplitter {{ background-color: #0a0; color: #a00; }} QProgressBar {{ border: 1px solid {4}; background-color: #000;}} QProgressBar::chunk {{ background-color: #0a0; width: 20px; }} QDoubleSpinBox {{ background-color: #888;}} QSpinBox {{ background-color: #888;}} QWebView {{ background-color: #888;}} QTreeView {{ color: {0}; border: 1px solid {4}}} QTabBar::tab {{ background-color: #000; color:{0}; border: 1px solid {4}; padding: 4px;}} QListView {{ color: {1}; border: 1px solid {4}}} """.format(str(self.settings['label_color']),str(self.settings['input_color']),str(self.settings['button_color']),str(self.settings['button_border_color']),str(self.settings['border_color'])) return style def showUpdateAvailable(self, dir, appversion): self.newupd = (dir, appversion) self.statusbar.showMessage(unicode(_translate("EliteOCR","New version of EliteOCR available: %s To download it go to Help > Update", None)) % appversion, 0) def restorePos(self): self.settings.reg.beginGroup("MainWindow") self.resize(self.settings.reg.value("size", QSize(400, 400)).toSize()) self.move(self.settings.reg.value("pos", QPoint(200, 200)).toPoint()) if self.settings.reg.value("maximized", False, type=bool): self.showMaximized() self.settings.reg.endGroup() def closeEvent(self, event): self.settings.reg.beginGroup("MainWindow") self.settings.reg.setValue("size", self.size()) self.settings.reg.setValue("pos", self.pos()) if self.windowState() == Qt.WindowMaximized: self.settings.reg.setValue("maximized", True) else: self.settings.reg.setValue("maximized", False) self.settings.reg.endGroup() self.settings.reg.setValue("public_mode", self.actionPublic_Mode.isChecked()) self.settings.reg.setValue("zoom_factor", self.factor.value()) self.settings.reg.sync() if not self.busyDialog is None: self.busyDialog.close() event.accept() def toggleMode(self): if self.actionPublic_Mode.isChecked(): msg = _translate("EliteOCR","Switching to public mode will clear the result table! Are you sure you want to do it?", None) reply = QMessageBox.question(self, 'Mode', msg, _translate("EliteOCR","Yes", None), _translate("EliteOCR","No", None)) if reply == 0: self.clearTable() self.cleanAllFields() self.cleanAllSnippets() else: self.actionPublic_Mode.setChecked(False) else: msg = _translate("EliteOCR","Switching to private mode will disable BPC and EDDN Export! Are you sure you want to do it?", None) reply = QMessageBox.question(self, 'Mode', msg, QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.Yes: self.enableButton(self.bpc_button, False) self.enableButton(self.eddn_button,False) else: self.actionPublic_Mode.setChecked(True) def loadPlugins(self): """Load known plugins""" #Trade Dangerous Export by gazelle (bgol) if isfile(self.settings.app_path+os.sep+"plugins"+os.sep+"TD_Export"+os.sep+"TD_Export.py"): plugin2 = imp.load_source('TD_Export', self.settings.app_path+\ os.sep+"plugins"+os.sep+"TD_Export"+os.sep+"TD_Export.py") self.tdexport = plugin2.TD_Export(self, self.settings.app_path.decode('windows-1252')) self.tdexport_button = QPushButton(self.centralwidget) self.tdexport_button.setText("Trade Dangerous Export") self.enableButton(self.tdexport_button, False) self.horizontalLayout_4.addWidget(self.tdexport_button) self.tdexport_button.clicked.connect(lambda: self.tdexport.run(self.export.tableToList(False, True))) def enablePluginButtons(self): if 'tdexport' in dir(self): if self.tdexport != None: self.enableButton(self.tdexport_button, True) def disablePluginButtons(self): if 'tdexport' in dir(self): if self.tdexport != None: self.enableButton(self.tdexport_button, False) def About(self): QMessageBox.about(self,"About", "EliteOCR\nVersion "+self.appversion+"\n\n"+\ "Contributors:\n"+\ "Seeebek, CapCap, Gazelle, GMib, Ph.Baumann\n\n"+\ "EliteOCR is capable of reading the entries in Elite: Dangerous markets screenshots.\n\n") def setupTable(self): """Add columns and column names to the table""" """ "self.result_table.setColumnCount(11) self.result_table.setHorizontalHeaderLabels(['station', 'commodity', 'sell', 'buy', 'demand', 'dem', 'supply', 'sup', 'timestamp','system','img_height']) """ self.result_table.setColumnHidden(8, True) self.result_table.setColumnHidden(10, True) #self.result_table.setColumnHidden(11, True) pass def openHelp(self): self.helpDialog = HelpDialog(self.settings.app_path.decode('windows-1252')) self.helpDialog.setModal(False) self.helpDialog.show() def openUpdate(self): self.updateDialog = UpdateDialog(self.settings.app_path.decode('windows-1252'), self.appversion, self.newupd) self.updateDialog.setModal(False) self.updateDialog.show() def openSettings(self): """Open settings dialog and reload settings""" settingsDialog = SettingsDialog(self.settings) settingsDialog.exec_() if self.settings["theme"] == "dark": self.dark_theme = True self.darkstyle = self.genDarkStyle() self.style = self.darkstyle else: self.dark_theme = False self.style = self.def_style #self.app.setStyleSheet("") self.app.setStyleSheet(self.style) self.resizeElements() def openEditor(self): editorDialog = EditorDialog(self.settings) editorDialog.exec_() def addAllScreenshots(self): dir = unicode(self.settings['screenshot_dir']).encode('windows-1252') #gen = (join(dir, file).decode('windows-1252') for file in listdir(dir) if isfile(join(dir, file))) gen = [join(dir, file).decode('windows-1252') for file in listdir(dir) if file.endswith('.bmp')] files = [] for file in gen: files.append(file) self.addFiles(files) def addFiles(self, screenshots = None): """Add files to the file list.""" if screenshots: files = screenshots else: if self.settings["native_dialog"]: files = QFileDialog.getOpenFileNames(self, "Open", self.settings['screenshot_dir']) else: files = QFileDialog.getOpenFileNames(self, "Open", self.settings['screenshot_dir'], options = QFileDialog.DontUseNativeDialog) if files == []: return first_item = None self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(len(files)) self.progress_bar.setValue(0) counter = 0 for file in files: file1 = unicode(file).encode('windows-1252') item = CustomQListWidgetItem(split(file1)[1], file1, self.settings) if first_item == None: first_item = item self.file_list.addItem(item) counter+=1 self.progress_bar.setValue(counter) self.progress_bar.setValue(0) self.file_list.itemClicked.connect(self.selectFile) self.save_button.setEnabled(False) self.enableButton(self.skip_button, False) #self.cleanAllFields() #self.cleanAllSnippets() if first_item !=None: self.selectFile(first_item) if self.ocr_button.isEnabled() and self.file_list.count() > 1: self.enableButton(self.ocr_all, True) self.cleanAllFields() self.cleanAllSnippets() def removeAllFiles(self): files = self.file_list.count() for i in xrange(files): item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item self.file_label.setText("-") scene = QGraphicsScene() self.previewSetScene(scene) self.save_button.setEnabled(False) self.skip_button.setEnabled(False) self.cleanAllFields() self.cleanAllSnippets() self.remove_button.setEnabled(False) self.remove_all_button.setEnabled(False) self.ocr_button.setEnabled(False) self.enableButton(self.zoom_button, False) def softRemoveFile(self): item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item def removeFile(self): """Remove selected file from file list.""" item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item self.file_label.setText("-") scene = QGraphicsScene() self.previewSetScene(scene) self.save_button.setEnabled(False) self.enableButton(self.skip_button, False) self.cleanAllFields() self.cleanAllSnippets() if self.file_list.currentItem(): self.selectFile(self.file_list.currentItem()) if self.file_list.count() == 0: self.remove_button.setEnabled(False) self.remove_all_button.setEnabled(False) self.ocr_button.setEnabled(False) self.enableButton(self.zoom_button, False) if self.file_list.count() < 2: self.enableButton(self.ocr_all, False) def selectFile(self, item): """Select clicked file and shows prewiev of the selected file.""" self.cleanAllFields() self.cleanAllSnippets() self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(20) self.progress_bar.setValue(0) self.color_image = item.loadColorImage() self.progress_bar.setValue(10) self.preview_image = item.loadPreviewImage(self.color_image, self) self.progress_bar.setValue(20) self.ocr_all_set = False #font = QFont("Consolas", 11) self.system_not_found.setText("") if len(item.system) == 0: self.system_not_found.setText(_translate("EliteOCR","System name not found in log files. Please read Help for more info.", None)) self.system_name.setText(item.system) if not item.station is None: self.station_name.setText(item.station) #self.system_name.setFont(font) self.file_list.setCurrentItem(item) self.file_label.setText(item.text()) self.setPreviewImage(self.preview_image) self.remove_button.setEnabled(True) self.remove_all_button.setEnabled(True) self.enableButton(self.continue_button, False) if not item.valid_market: self.system_not_found.setText(_translate("EliteOCR","File was not recognized as a valid market screenshot. Please read Help for more info.", None)) self.progress_bar.setValue(0) return self.ocr_button.setEnabled(True) self.enableButton(self.zoom_button, True) if self.file_list.count() > 1: self.enableButton(self.ocr_all, True) self.progress_bar.setValue(0) def setPreviewImage(self, image): """Show image in self.preview.""" factor = self.factor.value() pix = image.scaled(QSize(self.preview.size().width()*factor,self.preview.size().height()*factor), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.previewSetScene(scene) def previewSetScene(self, scene): """Shows scene in preview""" self.preview.setScene(scene) self.preview.show() def runOCRAll(self): self.ocr_all_set = True self.performOCR() def performOCR(self): """Send image to OCR and process the results""" self.OCRline = 0 self.busyDialog = BusyDialog(self) self.busyDialog.show() QApplication.processEvents() if self.file_list.currentItem().valid_market: self.current_result = OCR(self, self.color_image, self.file_list.currentItem().ocr_areas, self.settings["ocr_language"], self.file_list.currentItem()) self.busyDialog.close() """ try: self.current_result = OCR(self.color_image) except: QMessageBox.critical(self,"Error", "Error while performing OCR.\nPlease report the "+\ "problem to the developers through github, sourceforge or forum and provide the "+\ "screenshot which causes the problem.") return if self.current_result.station == None: QMessageBox.critical(self,"Error", "Screenshot not recognized.\n"+\ "Make sure you use a valid screenshot from the commodieties market. Should the "+\ "problem persist, please recalibrate the OCR areas with Settings->Calibrate.") return """ if len(self.current_result.commodities) < 1: QMessageBox.critical(self,"Error", "No results found!\nYou might be using an unsupported HUD color. Please read help for more information.") return self.drawOCRPreview() self.markCurrentRectangle() self.drawStationName() self.skip_button.setEnabled(True) self.enableButton(self.save_button, True) self.processOCRLine() self.system_name.setFocus() if self.settings['create_nn_images']: self.saveStationForTraining() else: self.nextFile() def addItemToTable(self): """Adds items from current OCR result line to the result table.""" tab = self.result_table res_station = unicode(self.station_name.text()).title() row_count = tab.rowCount() self.export_button.setEnabled(True) if self.actionPublic_Mode.isChecked(): self.bpc_button.setEnabled(True) self.eddn_button.setEnabled(True) self.enablePluginButtons() self.enableButton(self.clear_table, True) # check if no stock and not purchased if self.demand_num.text() == "" and self.supply_num.text() == "": self.nextLine() return #check for duplicates duplicate = False if self.settings["remove_dupli"]: for i in range(row_count): station = unicode(tab.item(i, 0).text()).title() com1 = unicode(tab.item(i, 1).text()).title() com2 = unicode(self.fields[0].text()).replace(',', '').title() if station == res_station and com1 == com2: duplicate = True if not duplicate: self.current_result.station.name.value = self.station_name.text() tab.insertRow(row_count) newitem = QTableWidgetItem(unicode(res_station).title().replace("'S", "'s")) tab.setItem(row_count, 0, newitem) for n, field in enumerate(self.fields): newitem = QTableWidgetItem(unicode(field.text()).replace(',', '').title()) tab.setItem(row_count, n+1, newitem) newitem = QTableWidgetItem(self.file_list.currentItem().timestamp) tab.setItem(row_count, 8, newitem) newitem = QTableWidgetItem(self.system_name.text()) tab.setItem(row_count, 9, newitem) newitem = QTableWidgetItem(unicode(self.file_list.currentItem().market_width)) tab.setItem(row_count, 10, newitem) tab.resizeColumnsToContents() tab.resizeRowsToContents() if self.settings['create_nn_images']: self.saveValuesForTraining() self.nextLine() def saveValuesForTraining(self): """Get OCR image/user values and save them away for later processing, and training neural net""" cres = self.current_result res = cres.commodities[self.OCRline] if not exists(self.training_image_dir): makedirs(self.training_image_dir) if not exists(self.training_image_dir+os.sep+"text"): makedirs(self.training_image_dir+os.sep+"text") if not exists(self.training_image_dir+os.sep+"numbers"): makedirs(self.training_image_dir+os.sep+"numbers") w = len(self.current_result.contrast_commodities_img) h = len(self.current_result.contrast_commodities_img[0]) for index, field, canvas, item in zip(range(0, len(self.canvases) - 1), self.fields, self.canvases, res.items): val = unicode(field.text())#.replace(',', '') if field in [self.sell, self.buy, self.demand_num, self.supply_num]: if val: snippet = self.cutImage(cres.contrast_commodities_img, item) #cv2.imshow('snippet', snippet) imageFilepath = self.training_image_dir + os.sep + u'numbers' + os.sep + unicode(val) + u'_' + unicode(w) + u'x' + unicode(h) +\ u'-' + unicode(int(time())) + u'-' +\ unicode(random.randint(10000, 100000)) + u'.png' cv2.imwrite(imageFilepath.encode('windows-1252'), snippet) elif field in [self.name]: if val: snippet = self.cutImage(cres.contrast_commodities_img, item) #cv2.imshow('snippet', snippet) imageFilepath = self.training_image_dir + os.sep + u'text' + os.sep + unicode(val) + u'_' + unicode(w) + u'x' + unicode(h) +\ u'-' + unicode(int(time())) + u'-' +\ unicode(random.randint(10000, 100000)) + u'.png' cv2.imwrite(imageFilepath.encode('windows-1252'), snippet) def saveStationForTraining(self): cres = self.current_result if not exists(self.training_image_dir): makedirs(self.training_image_dir) if not exists(self.training_image_dir+os.sep+"text"): makedirs(self.training_image_dir+os.sep+"text") w = len(self.current_result.contrast_commodities_img) h = len(self.current_result.contrast_commodities_img[0]) snippet = self.cutImage(cres.contrast_station_img, cres.station.name) val = self.station_name.text() imageFilepath = self.training_image_dir + os.sep + u'text' + os.sep + unicode(val) + u'_' + unicode(w) + u'x' + unicode(h) +\ u'-' + unicode(int(time())) + u'-' +\ unicode(random.randint(10000, 100000)) + u'.png' cv2.imwrite(imageFilepath.encode('windows-1252'), snippet) def cutImageForTraining(self, image, item): """Cut image snippet from a big image using points from item.""" snippet = image[item.y1:item.y2, item.x1:item.x2] return snippet def continueOCR(self): if self.ocr_all_set: self.nextFile() else: if self.settings['delete_files']: print "Deleted (continueOCR 458):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.removeFile() self.enableButton(self.continue_button, False) def nextLine(self): """Process next OCR result line.""" self.markCurrentRectangle(QPen(Qt.green)) self.OCRline += 1 if len(self.previewRects) > self.OCRline: self.markCurrentRectangle() self.processOCRLine() self.name.setFocus() else: self.save_button.setEnabled(False) self.enableButton(self.skip_button, False) self.cleanAllFields() self.cleanAllSnippets() if self.ocr_all_set: if self.settings['pause_at_end']: self.enableButton(self.continue_button, True) else: self.nextFile() else: if self.settings['delete_files']: if self.settings['pause_at_end']: self.enableButton(self.continue_button, True) else: print "Deleted (nextLine 486):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.removeFile() def nextFile(self): """OCR next file""" if self.file_list.currentRow() < self.file_list.count()-1: if self.settings['delete_files']: print "Deleted (nextFile 496):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.softRemoveFile() else: self.file_list.setCurrentRow(self.file_list.currentRow() + 1) self.color_image = self.file_list.currentItem().loadColorImage() self.preview_image = self.file_list.currentItem().loadPreviewImage(self.color_image, self) self.performOCR() #font = QFont("Consolas", 11) if self.OCRline == 0: if len(self.file_list.currentItem().system) > 0: self.system_not_found.setText("") self.system_name.setText(self.file_list.currentItem().system) if not self.file_list.currentItem().station is None: self.station_name.setText(self.file_list.currentItem().station) #self.system_name.setFont(font) else: self.system_name.setText("") #self.system_name.setFont(font) self.system_not_found.setText(_translate("EliteOCR","System name not found in log files. Make sure log directory path is set up correctly or add system name manually in the field below. Note: System name is necessary for BPC import!",None)) #self.system_name.setFocus() #self.system_name.selectAll() else: if self.settings['delete_files']: print "Deleted (nextFile 520):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.softRemoveFile() def clearTable(self): """Empty the result table.""" self.result_table.setRowCount(0) self.clear_table.setEnabled(False) self.export_button.setEnabled(False) self.bpc_button.setEnabled(False) self.enableButton(self.eddn_button, False) self.disablePluginButtons() def processOCRLine(self): """Process current OCR result line.""" if len(self.current_result.commodities) > self.OCRline: #font = QFont("Consolas", 11) res = self.current_result.commodities[self.OCRline] if self.OCRline > 0: autofill = True else: autofill = False if self.settings["auto_fill"]: for item in res.items: if item == None: continue if not item.confidence > 0.83: autofill = False if res.items[0] is None: autofill = False if res.items[1] is None: autofill = False if self.file_list.currentItem().market_width < 1065 and self.actionPublic_Mode.isChecked(): autofill = False self.save_button.setEnabled(False) self.enableButton(self.skip_button, True) QTimer.singleShot(1200, partial(self.enableButton, self.save_button, True)); #QTimer.singleShot(1500, partial(self.skip_button.setEnabled, True)); for field, canvas, item in zip(self.fields, self.canvases, res.items): if item != None: #field.clear() #field.addItems(item.optional_values) field.setText(item.value) #field.lineEdit().setFont(font) if not(self.settings["auto_fill"] and autofill): self.setConfidenceColor(field, item) self.drawSnippet(canvas, item) else: self.cleanSnippet(canvas) self.cleanField(field) if self.settings["auto_fill"] and autofill: self.addItemToTable() def setConfidenceColor(self, field, item): c = item.confidence #c = random.random() if self.dark_theme: if c > 0.83: color = "#000" if c <= 0.83 and c >0.67: color = "#666600" if c <= 0.67 and c >0.5: color = "#665100" if c <= 0.5 and c >0.34: color = "#663e00" if c <= 0.34 and c >0.17: color = "#662900" if c <= 0.17: color = "#661500" else: if c > 0.83: color = "#ffffff" if c <= 0.83 and c >0.67: color = "#ffffbf" if c <= 0.67 and c >0.5: color = "#fff2bf" if c <= 0.5 and c >0.34: color = "#ffe6bf" if c <= 0.34 and c >0.17: color = "#ffd9bf" if c <= 0.17: color = "#ffccbf" field.setStyleSheet("background: "+color+";") def drawOCRPreview(self): if self.current_result is None: self.setPreviewImage(self.preview_image) return factor = self.factor.value() res = self.current_result name = res.station img = self.preview_image old_h = img.height() old_w = img.width() pix = img.scaled(QSize(self.preview.size().width()*factor,self.preview.size().height()*factor), Qt.KeepAspectRatio, Qt.SmoothTransformation) #pix = img.scaled(self.preview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) new_h = pix.height() new_w = pix.width() ratio_h = old_h/float(new_h) ratio_w = old_w/float(new_w) self.scene = QGraphicsScene() self.scene.addPixmap(pix) #self.scene.addPixmap(img) self.previewRects = [] pen = QPen(Qt.yellow) redpen = QPen(Qt.red) bluepen = QPen(Qt.blue) greenpen = QPen(Qt.green) rect = self.addRect(self.scene, name, ratio_w, ratio_h, greenpen) counter = 0 for line in res.commodities: if counter < self.OCRline: rect = self.addRect(self.scene, line, ratio_w, ratio_h, greenpen) elif counter == self.OCRline: rect = self.addRect(self.scene, line, ratio_w, ratio_h, bluepen) else: if line.w < (0.02*old_w): rect = self.addRect(self.scene, line, ratio_w, ratio_h, redpen) else: rect = self.addRect(self.scene, line, ratio_w, ratio_h, pen) counter += 1 self.previewRects.append(rect) self.previewSetScene(self.scene) def addRect(self, scene, item, ratio_w, ratio_h, pen): """Adds a rectangle to scene and returns it.""" rect = scene.addRect(item.x1/ratio_w -3, item.y1/ratio_h -3, item.w/ratio_w +7, item.h/ratio_h +6, pen) return rect def markCurrentRectangle(self, pen=QPen(Qt.blue)): self.previewRects[self.OCRline].setPen(pen) def cutImage(self, image, item): """Cut image snippet from a big image using points from item.""" snippet = image[item.y1 - 5:item.y2 + 5, item.x1 - 5:item.x2 + 5] return snippet def drawSnippet(self, graphicsview, item): """Draw single result item to graphicsview""" res = self.current_result snippet = self.cutImage(res.contrast_commodities_img, item) if self.dark_theme: snippet = 255 - snippet #cv2.imwrite('snippets/'+unicode(self.currentsnippet)+'.png',snippet) #self.currentsnippet += 1 processedimage = array2qimage(snippet) pix = QPixmap() pix.convertFromImage(processedimage) pix = pix.scaled(graphicsview.width(), graphicsview.height(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) graphicsview.setScene(scene) graphicsview.show() def drawStationName(self): """Draw station name snippet to station_name_img""" res = self.current_result name = res.station.name #self.station_name.setText('') #self.station_name.clear() #self.station_name.addItems(name.optional_values) if not self.file_list.currentItem().station is None: self.station_name.setText(self.file_list.currentItem().station) else: self.station_name.setText(name.value) #font = QFont("Consolas", 11) #self.station_name.lineEdit().setFont(font) #self.setConfidenceColor(self.station_name, name) img = self.cutImage(res.contrast_station_img, name) if self.dark_theme: img = 255 - img processedimage = array2qimage(img) pix = QPixmap() pix.convertFromImage(processedimage) if self.station_name_img.height() < pix.height(): pix = pix.scaled(self.station_name_img.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.station_name_img.setScene(scene) self.station_name_img.show() def cleanAllFields(self): for field in self.fields: self.cleanField(field) self.cleanField(self.station_name) self.save_button.setEnabled(False) self.enableButton(self.skip_button, False) def cleanField(self, field): field.setText('') if self.dark_theme: field.setStyleSheet("background: #000;") else: field.setStyleSheet("background: #fff;") #field.lineEdit().setStyleSheet("") #field.clear() def cleanAllSnippets(self): for field in self.canvases: self.cleanSnippet(field) self.cleanSnippet(self.station_name_img) def cleanSnippet(self, graphicsview): scene = QGraphicsScene() graphicsview.setScene(scene) def enableButton(self, button, switch): button.setEnabled(switch) if self.dark_theme: self.app.setStyleSheet("") self.app.setStyleSheet(self.style) self.repaint()
class UpdateDialog(QDialog, Ui_Update): def __init__(self, path, appversion, newupd): QDialog.__init__(self) self.app_path = path self.setupUi(self) self.exiting = False self.appversion = appversion self.newupd = newupd self.filepath = "" if not newupd is None: self.label.setText("New version found: "+newupd[1]) self.download.setEnabled(True) #self.download.setEnabled(True) self.download.clicked.connect(self.downloadFile) self.check.clicked.connect(self.checkUpdate) self.thread = Worker() self.connect(self.thread, SIGNAL("output(QString, QString)"), self.showUpdateAvailable) self.connect(self.thread, SIGNAL("end()"), self.showNoUpdate) self.downloader = Downloader(self) self.connect(self.downloader, SIGNAL("loaded(int, int)"), self.updateProgress) self.connect(self.downloader, SIGNAL("finished()"), self.downloadFinished) self.connect(self.downloader, SIGNAL("finishederror()"), self.downloadFinishedError) def closeEvent(self, event): self.emit(SIGNAL("exiting()")) event.accept() def downloadFile(self): self.check.setEnabled(False) self.download.setEnabled(False) if not self.newupd is None: self.label.setText("Starting download.") url = "http://sourceforge.net/projects/eliteocr/files/"+self.newupd[0]+"/EliteOCR."+self.newupd[1]+".zip" #url = "http://blog.fancyrhino.com/wp-content/uploads/2014/03/3.jpg" if not isdir(unicode(self.app_path)+u""+ os.sep +".."+ os.sep +"update"+ os.sep +""): makedirs(unicode(self.app_path)+u""+ os.sep +".."+ os.sep +"update"+ os.sep +"") self.filepath = unicode(self.app_path)+u""+ os.sep +".."+ os.sep +"update"+ os.sep +"EliteOCR."+unicode(self.newupd[1])+u".zip.part" #print self.filepath self.downloader.get(url, self.filepath) def downloadFinished(self): if isfile(self.filepath[:-5]): remove(self.filepath[:-5]) rename(self.filepath, self.filepath[:-5]) self.progress_bar.setMaximum(1) self.progress_bar.setValue(0) self.label.setText("Download finished. You can find it in the update directory.") subprocess.Popen(r'explorer /select,"'+unicode(self.app_path).encode(sys.getfilesystemencoding())+ os.sep +".."+ os.sep +"update"+ os.sep +"EliteOCR."+unicode(self.newupd[1]).encode(sys.getfilesystemencoding())+".zip") def downloadFinishedError(self): self.progress_bar.setMaximum(1) self.progress_bar.setValue(0) self.label.setText("Error while downloading.") def updateProgress(self, done, total): self.progress_bar.setMaximum(total) self.progress_bar.setValue(done) self.label.setText("Downloading: "+unicode("%.2f" % (done/1048576.0))+"MB / "+unicode("%.2f" % (total/1048576.0))+"MB") def showNoUpdate(self): self.label.setText("No updates found.") self.check.setEnabled(True) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(1) self.progress_bar.setValue(0) def showUpdateAvailable(self, dir, appversion): self.newupd = (dir, appversion) self.label.setText("New version found: "+appversion) self.check.setEnabled(True) self.download.setEnabled(True) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(1) self.progress_bar.setValue(0) def checkUpdate(self): self.label.setText("Looking for new updates") self.check.setEnabled(False) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(0) self.progress_bar.setValue(0) self.thread.check(self.appversion)
class UpdateDialog(QDialog, Ui_Update): def __init__(self, path, appversion, newupd): QDialog.__init__(self) self.app_path = path self.setupUi(self) self.exiting = False self.appversion = appversion self.newupd = newupd self.filepath = "" if not newupd is None: self.label.setText("New version found: " + newupd[1]) self.download.setEnabled(True) #self.download.setEnabled(True) self.download.clicked.connect(self.downloadFile) self.check.clicked.connect(self.checkUpdate) self.thread = Worker() self.connect(self.thread, SIGNAL("output(QString, QString)"), self.showUpdateAvailable) self.connect(self.thread, SIGNAL("end()"), self.showNoUpdate) self.downloader = Downloader(self) self.connect(self.downloader, SIGNAL("loaded(int, int)"), self.updateProgress) self.connect(self.downloader, SIGNAL("finished()"), self.downloadFinished) self.connect(self.downloader, SIGNAL("finishederror()"), self.downloadFinishedError) def closeEvent(self, event): self.emit(SIGNAL("exiting()")) event.accept() def downloadFile(self): self.check.setEnabled(False) self.download.setEnabled(False) if not self.newupd is None: self.label.setText("Starting download.") url = "http://sourceforge.net/projects/eliteocr/files/" + self.newupd[ 0] + "/EliteOCR." + self.newupd[1] + ".zip" #url = "http://blog.fancyrhino.com/wp-content/uploads/2014/03/3.jpg" if not isdir( unicode(self.app_path) + u"" + os.sep + ".." + os.sep + "update" + os.sep + ""): makedirs( unicode(self.app_path) + u"" + os.sep + ".." + os.sep + "update" + os.sep + "") self.filepath = unicode( self.app_path ) + u"" + os.sep + ".." + os.sep + "update" + os.sep + "EliteOCR." + unicode( self.newupd[1]) + u".zip.part" #print self.filepath self.downloader.get(url, self.filepath) def downloadFinished(self): if isfile(self.filepath[:-5]): remove(self.filepath[:-5]) rename(self.filepath, self.filepath[:-5]) self.progress_bar.setMaximum(1) self.progress_bar.setValue(0) self.label.setText( "Download finished. You can find it in the update directory.") subprocess.Popen( r'explorer /select,"' + unicode(self.app_path).encode(sys.getfilesystemencoding()) + os.sep + ".." + os.sep + "update" + os.sep + "EliteOCR." + unicode(self.newupd[1]).encode(sys.getfilesystemencoding()) + ".zip") def downloadFinishedError(self): self.progress_bar.setMaximum(1) self.progress_bar.setValue(0) self.label.setText("Error while downloading.") def updateProgress(self, done, total): self.progress_bar.setMaximum(total) self.progress_bar.setValue(done) self.label.setText("Downloading: " + unicode("%.2f" % (done / 1048576.0)) + "MB / " + unicode("%.2f" % (total / 1048576.0)) + "MB") def showNoUpdate(self): self.label.setText("No updates found.") self.check.setEnabled(True) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(1) self.progress_bar.setValue(0) def showUpdateAvailable(self, dir, appversion): self.newupd = (dir, appversion) self.label.setText("New version found: " + appversion) self.check.setEnabled(True) self.download.setEnabled(True) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(1) self.progress_bar.setValue(0) def checkUpdate(self): self.label.setText("Looking for new updates") self.check.setEnabled(False) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(0) self.progress_bar.setValue(0) self.thread.check(self.appversion)
class EliteOCR(QMainWindow, Ui_MainWindow): def __init__(self): QMainWindow.__init__( self) #QMainWindow.__init__(self, None, Qt.FramelessWindowHint) self.setupUi(self) self.appversion = appversion self.setupTable() self.settings = Settings(self) self.export = Export(self) self.actionPublic_Mode.setChecked(self.settings["public_mode"]) self.factor.setValue(self.settings["zoom_factor"]) self.ocr_all_set = False self.color_image = None self.preview_image = None self.current_result = None self.newupd = None self.zoom = False self.minres = 0 self.fields = [ self.name, self.sell, self.buy, self.demand_num, self.demand, self.supply_num, self.supply ] self.canvases = [ self.name_img, self.sell_img, self.buy_img, self.demand_img, self.demand_text_img, self.supply_img, self.supply_text_img ] #setup buttons self.add_button.clicked.connect(self.addFiles) self.remove_button.clicked.connect(self.removeFile) self.remove_all_button.clicked.connect(self.removeAllFiles) self.add_all_button.clicked.connect(self.addAllScreenshots) self.save_button.clicked.connect(self.addItemToTable) self.skip_button.clicked.connect(self.nextLine) self.continue_button.clicked.connect(self.continueOCR) self.ocr_button.clicked.connect(self.performOCR) self.ocr_all.clicked.connect(self.runOCRAll) self.export_button.clicked.connect(self.export.exportToFile) self.bpc_button.clicked.connect(self.export.bpcExport) self.eddn_button.clicked.connect(self.export.eddnExport) self.clear_table.clicked.connect(self.clearTable) self.zoom_button.clicked.connect(self.drawOCRPreview) QObject.connect(self.actionHelp, SIGNAL('triggered()'), self.openHelp) QObject.connect(self.actionUpdate, SIGNAL('triggered()'), self.openUpdate) QObject.connect(self.actionAbout, SIGNAL('triggered()'), self.About) QObject.connect(self.actionOpen, SIGNAL('triggered()'), self.addFiles) QObject.connect(self.actionPreferences, SIGNAL('triggered()'), self.openSettings) QObject.connect(self.actionPublic_Mode, SIGNAL('triggered()'), self.toggleMode) QObject.connect(self.actionCommodity_Editor, SIGNAL('triggered()'), self.openEditor) self.error_close = False #set up required items for nn self.training_image_dir = unicode( self.settings.app_path.decode( 'windows-1252')) + u"\\nn_training_images\\" self.loadPlugins() self.restorePos() self.eddnthread = EDDNExport(self) QObject.connect(self.eddnthread, SIGNAL('finished(QString)'), self.export.eddnFinished) QObject.connect(self.eddnthread, SIGNAL('update(int,int)'), self.export.eddnUpdate) self.checkupadte = self.settings["updates_check"] self.thread = Worker() self.connect(self.thread, SIGNAL("output(QString, QString)"), self.showUpdateAvailable) if self.checkupadte: self.thread.check(self.appversion) if not self.settings.reg.contains('info_accepted'): self.infoDialog = InfoDialog() self.infoDialog.exec_() else: if not self.settings['info_accepted']: self.infoDialog = InfoDialog() self.infoDialog.exec_() def showUpdateAvailable(self, dir, appversion): self.newupd = (dir, appversion) self.statusbar.showMessage( unicode( _translate( "EliteOCR", "New version of EliteOCR available: %s To download it go to Help > Update", None)) % appversion, 0) def restorePos(self): self.settings.reg.beginGroup("MainWindow") self.resize(self.settings.reg.value("size", QSize(400, 400)).toSize()) self.move(self.settings.reg.value("pos", QPoint(200, 200)).toPoint()) self.settings.reg.endGroup() def closeEvent(self, event): self.settings.reg.beginGroup("MainWindow") self.settings.reg.setValue("size", self.size()) self.settings.reg.setValue("pos", self.pos()) self.settings.reg.endGroup() self.settings.reg.setValue("public_mode", self.actionPublic_Mode.isChecked()) self.settings.reg.setValue("zoom_factor", self.factor.value()) self.settings.reg.sync() event.accept() def toggleMode(self): if self.actionPublic_Mode.isChecked(): msg = _translate( "EliteOCR", "Switching to public mode will clear the result table! Are you sure you want to do it?", None) reply = QMessageBox.question(self, 'Mode', msg, _translate("EliteOCR", "Yes", None), _translate("EliteOCR", "No", None)) if reply == 0: self.clearTable() self.cleanAllFields() self.cleanAllSnippets() else: self.actionPublic_Mode.setChecked(False) else: msg = _translate( "EliteOCR", "Switching to private mode will disable BPC and EDDN Export! Are you sure you want to do it?", None) reply = QMessageBox.question(self, 'Mode', msg, QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.Yes: self.bpc_button.setEnabled(False) self.eddn_button.setEnabled(False) else: self.actionPublic_Mode.setChecked(True) def loadPlugins(self): """Load known plugins""" #Trade Dangerous Export by gazelle (bgol) if isfile(self.settings.app_path + "\\plugins\\TD_Export\\TD_Export.py"): plugin2 = imp.load_source('TD_Export', self.settings.app_path+\ "\\plugins\\TD_Export\\TD_Export.py") self.tdexport = plugin2.TD_Export( self, self.settings.app_path.decode('windows-1252')) self.tdexport_button = QPushButton(self.centralwidget) self.tdexport_button.setText("Trade Dangerous Export") self.tdexport_button.setEnabled(False) self.horizontalLayout_2.addWidget(self.tdexport_button) self.tdexport_button.clicked.connect(lambda: self.tdexport.run( self.export.tableToList(False, True))) def enablePluginButtons(self): if 'tdexport' in dir(self): if self.tdexport != None: self.tdexport_button.setEnabled(True) def disablePluginButtons(self): if 'tdexport' in dir(self): if self.tdexport != None: self.tdexport_button.setEnabled(False) def About(self): QMessageBox.about(self,"About", "EliteOCR\nVersion "+self.appversion+"\n\n"+\ "Contributors:\n"+\ "Seeebek, CapCap, Gazelle, GMib, Ph.Baumann\n\n"+\ "EliteOCR is capable of reading the entries in Elite: Dangerous markets screenshots.\n\n") def setupTable(self): """Add columns and column names to the table""" """ "self.result_table.setColumnCount(11) self.result_table.setHorizontalHeaderLabels(['station', 'commodity', 'sell', 'buy', 'demand', 'dem', 'supply', 'sup', 'timestamp','system','img_height']) """ self.result_table.setColumnHidden(8, True) self.result_table.setColumnHidden(10, True) #self.result_table.setColumnHidden(11, True) pass def openHelp(self): self.helpDialog = HelpDialog( self.settings.app_path.decode('windows-1252')) self.helpDialog.setModal(False) self.helpDialog.show() def openUpdate(self): self.updateDialog = UpdateDialog( self.settings.app_path.decode('windows-1252'), self.appversion, self.newupd) self.updateDialog.setModal(False) self.updateDialog.show() def openSettings(self): """Open settings dialog and reload settings""" settingsDialog = SettingsDialog(self.settings) settingsDialog.exec_() def openEditor(self): editorDialog = EditorDialog(self.settings) editorDialog.exec_() def addAllScreenshots(self): dir = unicode(self.settings['screenshot_dir']).encode('windows-1252') #gen = (join(dir, file).decode('windows-1252') for file in listdir(dir) if isfile(join(dir, file))) gen = [ join(dir, file).decode('windows-1252') for file in listdir(dir) if file.endswith('.bmp') ] files = [] for file in gen: files.append(file) self.addFiles(files) def addFiles(self, screenshots=None): """Add files to the file list.""" if screenshots: files = screenshots else: if self.settings["native_dialog"]: files = QFileDialog.getOpenFileNames( self, "Open", self.settings['screenshot_dir']) else: files = QFileDialog.getOpenFileNames( self, "Open", self.settings['screenshot_dir'], options=QFileDialog.DontUseNativeDialog) if files == []: return first_item = None self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(len(files)) self.progress_bar.setValue(0) counter = 0 for file in files: file1 = unicode(file).encode('windows-1252') item = CustomQListWidgetItem(split(file1)[1], file1, self.settings) if first_item == None: first_item = item self.file_list.addItem(item) counter += 1 self.progress_bar.setValue(counter) self.progress_bar.setValue(0) self.file_list.itemClicked.connect(self.selectFile) self.save_button.setEnabled(False) self.skip_button.setEnabled(False) #self.cleanAllFields() #self.cleanAllSnippets() if first_item != None: self.selectFile(first_item) if self.ocr_button.isEnabled() and self.file_list.count() > 1: self.ocr_all.setEnabled(True) self.cleanAllFields() self.cleanAllSnippets() def removeAllFiles(self): files = self.file_list.count() for i in xrange(files): item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item self.file_label.setText("-") scene = QGraphicsScene() self.previewSetScene(scene) self.save_button.setEnabled(False) self.skip_button.setEnabled(False) self.cleanAllFields() self.cleanAllSnippets() self.remove_button.setEnabled(False) self.remove_all_button.setEnabled(False) self.ocr_button.setEnabled(False) self.zoom_button.setEnabled(False) def softRemoveFile(self): item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item def removeFile(self): """Remove selected file from file list.""" item = self.file_list.currentItem() self.file_list.takeItem(self.file_list.currentRow()) del item self.file_label.setText("-") scene = QGraphicsScene() self.previewSetScene(scene) self.save_button.setEnabled(False) self.skip_button.setEnabled(False) self.cleanAllFields() self.cleanAllSnippets() if self.file_list.currentItem(): self.selectFile(self.file_list.currentItem()) if self.file_list.count() == 0: self.remove_button.setEnabled(False) self.remove_all_button.setEnabled(False) self.ocr_button.setEnabled(False) self.zoom_button.setEnabled(False) if self.file_list.count() < 2: self.ocr_all.setEnabled(False) def selectFile(self, item): """Select clicked file and shows prewiev of the selected file.""" self.cleanAllFields() self.cleanAllSnippets() self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(20) self.progress_bar.setValue(0) self.color_image = item.loadColorImage() self.progress_bar.setValue(10) self.preview_image = item.loadPreviewImage(self.color_image, self) self.progress_bar.setValue(20) self.ocr_all_set = False font = QFont() font.setPointSize(11) self.system_not_found.setText("") if len(item.system) == 0: self.system_not_found.setText( _translate( "EliteOCR", "System name not found in log files. Make sure log directory path is set up correctly or add system name manually in the field below. Note: System name is necessary for BPC import!", None)) self.system_name.setText(item.system) self.system_name.setFont(font) self.file_list.setCurrentItem(item) self.file_label.setText(item.text()) self.setPreviewImage(self.preview_image) self.remove_button.setEnabled(True) self.remove_all_button.setEnabled(True) self.continue_button.setEnabled(False) if not item.valid_market: self.system_not_found.setText( _translate( "EliteOCR", "File was not recognized as a valid market screenshot. If the file is valid please report the issue in the forum.", None)) self.progress_bar.setValue(0) return self.ocr_button.setEnabled(True) self.zoom_button.setEnabled(True) if self.file_list.count() > 1: self.ocr_all.setEnabled(True) self.progress_bar.setValue(0) def setPreviewImage(self, image): """Show image in self.preview.""" factor = self.factor.value() pix = image.scaled( QSize(self.preview.size().width() * factor, self.preview.size().height() * factor), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.previewSetScene(scene) def previewSetScene(self, scene): """Shows scene in preview""" self.preview.setScene(scene) self.preview.show() def runOCRAll(self): self.ocr_all_set = True self.performOCR() def performOCR(self): """Send image to OCR and process the results""" self.OCRline = 0 busyDialog = BusyDialog(self) busyDialog.show() QApplication.processEvents() if self.file_list.currentItem().valid_market: self.current_result = OCR(self, self.color_image, self.file_list.currentItem().ocr_areas, self.settings["ocr_language"], self.file_list.currentItem()) """ try: self.current_result = OCR(self.color_image) except: QMessageBox.critical(self,"Error", "Error while performing OCR.\nPlease report the "+\ "problem to the developers through github, sourceforge or forum and provide the "+\ "screenshot which causes the problem.") return if self.current_result.station == None: QMessageBox.critical(self,"Error", "Screenshot not recognized.\n"+\ "Make sure you use a valid screenshot from the commodieties market. Should the "+\ "problem persist, please recalibrate the OCR areas with Settings->Calibrate.") return """ self.drawOCRPreview() self.markCurrentRectangle() self.drawStationName() self.skip_button.setEnabled(True) self.save_button.setEnabled(True) self.processOCRLine() if self.settings['create_nn_images']: self.saveStationForTraining() else: self.nextFile() def addItemToTable(self): """Adds items from current OCR result line to the result table.""" tab = self.result_table res_station = unicode(self.station_name.currentText()).title() row_count = tab.rowCount() self.export_button.setEnabled(True) if self.actionPublic_Mode.isChecked(): self.bpc_button.setEnabled(True) self.eddn_button.setEnabled(True) self.enablePluginButtons() self.clear_table.setEnabled(True) #check for duplicates duplicate = False if self.settings["remove_dupli"]: for i in range(row_count): station = unicode(tab.item(i, 0).text()).title() com1 = unicode(tab.item(i, 1).text()).title() com2 = unicode(self.fields[0].currentText()).replace( ',', '').title() if station == res_station and com1 == com2: duplicate = True if not duplicate: self.current_result.station.name.value = self.station_name.currentText( ) tab.insertRow(row_count) newitem = QTableWidgetItem( unicode(res_station).title().replace("'S", "'s")) tab.setItem(row_count, 0, newitem) for n, field in enumerate(self.fields): newitem = QTableWidgetItem( unicode(field.currentText()).replace(',', '').title()) tab.setItem(row_count, n + 1, newitem) newitem = QTableWidgetItem(self.file_list.currentItem().timestamp) tab.setItem(row_count, 8, newitem) newitem = QTableWidgetItem(self.system_name.text()) tab.setItem(row_count, 9, newitem) newitem = QTableWidgetItem( unicode(self.file_list.currentItem().market_width)) tab.setItem(row_count, 10, newitem) tab.resizeColumnsToContents() tab.resizeRowsToContents() if self.settings['create_nn_images']: self.saveValuesForTraining() self.nextLine() def saveValuesForTraining(self): """Get OCR image/user values and save them away for later processing, and training neural net""" cres = self.current_result res = cres.commodities[self.OCRline] if not exists(self.training_image_dir): makedirs(self.training_image_dir) if not exists(self.training_image_dir + "\\text"): makedirs(self.training_image_dir + "\\text") if not exists(self.training_image_dir + "\\numbers"): makedirs(self.training_image_dir + "\\numbers") w = len(self.current_result.contrast_commodities_img) h = len(self.current_result.contrast_commodities_img[0]) for index, field, canvas, item in zip(range(0, len(self.canvases) - 1), self.fields, self.canvases, res.items): val = unicode(field.currentText()).replace(',', '') if field in [ self.sell, self.buy, self.demand_num, self.supply_num ]: if val: snippet = self.cutImage(cres.contrast_commodities_img, item) #cv2.imshow('snippet', snippet) imageFilepath = self.training_image_dir + u'\\numbers\\' + unicode(val) + u'_' + unicode(w) + u'x' + unicode(h) +\ u'-' + unicode(int(time())) + u'-' +\ unicode(random.randint(10000, 100000)) + u'.png' cv2.imwrite(imageFilepath.encode('windows-1252'), snippet) elif field in [self.name]: if val: snippet = self.cutImage(cres.contrast_commodities_img, item) #cv2.imshow('snippet', snippet) imageFilepath = self.training_image_dir + u'\\text\\' + unicode(val) + u'_' + unicode(w) + u'x' + unicode(h) +\ u'-' + unicode(int(time())) + u'-' +\ unicode(random.randint(10000, 100000)) + u'.png' cv2.imwrite(imageFilepath.encode('windows-1252'), snippet) def saveStationForTraining(self): cres = self.current_result if not exists(self.training_image_dir): makedirs(self.training_image_dir) if not exists(self.training_image_dir + "\\text"): makedirs(self.training_image_dir + "\\text") w = len(self.current_result.contrast_commodities_img) h = len(self.current_result.contrast_commodities_img[0]) snippet = self.cutImage(cres.contrast_station_img, cres.station.name) val = self.station_name.currentText() imageFilepath = self.training_image_dir + u'\\text\\' + unicode(val) + u'_' + unicode(w) + u'x' + unicode(h) +\ u'-' + unicode(int(time())) + u'-' +\ unicode(random.randint(10000, 100000)) + u'.png' cv2.imwrite(imageFilepath.encode('windows-1252'), snippet) def cutImageForTraining(self, image, item): """Cut image snippet from a big image using points from item.""" snippet = image[item.y1:item.y2, item.x1:item.x2] return snippet def continueOCR(self): if self.ocr_all_set: self.nextFile() else: if self.settings['delete_files']: print "Deleted (continueOCR 458):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.removeFile() self.continue_button.setEnabled(False) def nextLine(self): """Process next OCR result line.""" self.markCurrentRectangle(QPen(Qt.green)) self.OCRline += 1 if len(self.previewRects) > self.OCRline: self.markCurrentRectangle() self.processOCRLine() else: self.save_button.setEnabled(False) self.skip_button.setEnabled(False) self.cleanAllFields() self.cleanAllSnippets() if self.ocr_all_set: if self.settings['pause_at_end']: self.continue_button.setEnabled(True) else: self.nextFile() else: if self.settings['delete_files']: if self.settings['pause_at_end']: self.continue_button.setEnabled(True) else: print "Deleted (nextLine 486):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.removeFile() def nextFile(self): """OCR next file""" if self.file_list.currentRow() < self.file_list.count() - 1: if self.settings['delete_files']: print "Deleted (nextFile 496):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.softRemoveFile() else: self.file_list.setCurrentRow(self.file_list.currentRow() + 1) self.color_image = self.file_list.currentItem().loadColorImage() self.preview_image = self.file_list.currentItem().loadPreviewImage( self.color_image, self) self.performOCR() font = QFont() font.setPointSize(11) if self.OCRline == 0: if len(self.file_list.currentItem().system) > 0: self.system_not_found.setText("") self.system_name.setText( self.file_list.currentItem().system) self.system_name.setFont(font) else: self.system_name.setText("") self.system_name.setFont(font) self.system_not_found.setText( _translate( "EliteOCR", "System name not found in log files. Make sure log directory path is set up correctly or add system name manually in the field below. Note: System name is necessary for BPC import!", None)) self.system_name.setFocus() self.system_name.selectAll() else: if self.settings['delete_files']: print "Deleted (nextFile 520):" print self.file_list.currentItem().text() remove(self.file_list.currentItem().hiddentext) self.softRemoveFile() def clearTable(self): """Empty the result table.""" self.result_table.setRowCount(0) self.clear_table.setEnabled(False) self.export_button.setEnabled(False) self.bpc_button.setEnabled(False) self.eddn_button.setEnabled(False) self.disablePluginButtons() def processOCRLine(self): """Process current OCR result line.""" if len(self.current_result.commodities) > self.OCRline: font = QFont() font.setPointSize(11) res = self.current_result.commodities[self.OCRline] if self.OCRline > 0: autofill = True else: autofill = False if self.settings["auto_fill"]: for item in res.items: if item == None: continue if not item.confidence > 0.83: autofill = False if res.items[0] is None: autofill = False if res.items[1] is None: autofill = False if self.file_list.currentItem( ).market_width < 1065 and self.actionPublic_Mode.isChecked(): autofill = False self.save_button.setEnabled(False) self.skip_button.setEnabled(True) QTimer.singleShot(1200, partial(self.save_button.setEnabled, True)) #QTimer.singleShot(1500, partial(self.skip_button.setEnabled, True)); for field, canvas, item in zip(self.fields, self.canvases, res.items): if item != None: field.clear() field.addItems(item.optional_values) field.setEditText(item.value) field.lineEdit().setFont(font) if not (self.settings["auto_fill"] and autofill): self.setConfidenceColor(field, item) self.drawSnippet(canvas, item) else: self.cleanSnippet(canvas) self.cleanField(field) if self.settings["auto_fill"] and autofill: self.addItemToTable() def setConfidenceColor(self, field, item): c = item.confidence if c > 0.83: color = "#ffffff" if c <= 0.83 and c > 0.67: color = "#ffffbf" if c <= 0.67 and c > 0.5: color = "#fff2bf" if c <= 0.5 and c > 0.34: color = "#ffe6bf" if c <= 0.34 and c > 0.17: color = "#ffd9bf" if c <= 0.17: color = "#ffccbf" field.lineEdit().setStyleSheet("QLineEdit{background: " + color + ";}") def drawOCRPreview(self): if self.current_result is None: self.setPreviewImage(self.preview_image) return factor = self.factor.value() res = self.current_result name = res.station img = self.preview_image old_h = img.height() old_w = img.width() pix = img.scaled( QSize(self.preview.size().width() * factor, self.preview.size().height() * factor), Qt.KeepAspectRatio, Qt.SmoothTransformation) #pix = img.scaled(self.preview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) new_h = pix.height() new_w = pix.width() ratio_h = old_h / float(new_h) ratio_w = old_w / float(new_w) self.scene = QGraphicsScene() self.scene.addPixmap(pix) #self.scene.addPixmap(img) self.previewRects = [] pen = QPen(Qt.yellow) redpen = QPen(Qt.red) bluepen = QPen(Qt.blue) greenpen = QPen(Qt.green) rect = self.addRect(self.scene, name, ratio_w, ratio_h, greenpen) counter = 0 for line in res.commodities: if counter < self.OCRline: rect = self.addRect(self.scene, line, ratio_w, ratio_h, greenpen) elif counter == self.OCRline: rect = self.addRect(self.scene, line, ratio_w, ratio_h, bluepen) else: if line.w < (0.02 * old_w): rect = self.addRect(self.scene, line, ratio_w, ratio_h, redpen) else: rect = self.addRect(self.scene, line, ratio_w, ratio_h, pen) counter += 1 self.previewRects.append(rect) self.previewSetScene(self.scene) def addRect(self, scene, item, ratio_w, ratio_h, pen): """Adds a rectangle to scene and returns it.""" rect = scene.addRect(item.x1 / ratio_w - 3, item.y1 / ratio_h - 3, item.w / ratio_w + 7, item.h / ratio_h + 6, pen) return rect def markCurrentRectangle(self, pen=QPen(Qt.blue)): self.previewRects[self.OCRline].setPen(pen) def cutImage(self, image, item): """Cut image snippet from a big image using points from item.""" snippet = image[item.y1 - 5:item.y2 + 5, item.x1 - 5:item.x2 + 5] return snippet def drawSnippet(self, graphicsview, item): """Draw single result item to graphicsview""" res = self.current_result snippet = self.cutImage(res.contrast_commodities_img, item) #cv2.imwrite('snippets/'+unicode(self.currentsnippet)+'.png',snippet) #self.currentsnippet += 1 processedimage = array2qimage(snippet) pix = QPixmap() pix.convertFromImage(processedimage) if graphicsview.height() < pix.height(): pix = pix.scaled(graphicsview.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) graphicsview.setScene(scene) graphicsview.show() def drawStationName(self): """Draw station name snippet to station_name_img""" res = self.current_result name = res.station.name self.station_name.clear() self.station_name.addItems(name.optional_values) self.station_name.setEditText(name.value) font = QFont() font.setPointSize(11) self.station_name.lineEdit().setFont(font) self.setConfidenceColor(self.station_name, name) img = self.cutImage(res.contrast_station_img, name) processedimage = array2qimage(img) pix = QPixmap() pix.convertFromImage(processedimage) if self.station_name_img.height() < pix.height(): pix = pix.scaled(self.station_name_img.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) scene = QGraphicsScene() scene.addPixmap(pix) self.station_name_img.setScene(scene) self.station_name_img.show() def cleanAllFields(self): for field in self.fields: self.cleanField(field) self.cleanField(self.station_name) self.save_button.setEnabled(False) self.skip_button.setEnabled(False) def cleanField(self, field): field.setEditText('') field.lineEdit().setStyleSheet("") field.clear() def cleanAllSnippets(self): for field in self.canvases: self.cleanSnippet(field) self.cleanSnippet(self.station_name_img) def cleanSnippet(self, graphicsview): scene = QGraphicsScene() graphicsview.setScene(scene)