mirror of
https://github.com/283375/arcaea-offline-pyside-ui.git
synced 2025-04-21 10:10:17 +00:00
wip: arcaea-offline==0.2.0
This commit is contained in:
parent
a9d2b5f75d
commit
ecd4ed619e
@ -26,8 +26,6 @@ class FuzzySearchCompleterModel(QStandardItemModel):
|
|||||||
item = QStandardItem(kw)
|
item = QStandardItem(kw)
|
||||||
item.setData(kw)
|
item.setData(kw)
|
||||||
item.setData(displayText, Qt.ItemDataRole.UserRole + 75)
|
item.setData(displayText, Qt.ItemDataRole.UserRole + 75)
|
||||||
item.setData(
|
item.setData(f"{chart.song_id}, {chart.set}", Qt.ItemDataRole.UserRole + 76)
|
||||||
f"{chart.song_id}, {chart.package_id}", Qt.ItemDataRole.UserRole + 76
|
|
||||||
)
|
|
||||||
item.setData(chart, Qt.ItemDataRole.UserRole + 10)
|
item.setData(chart, Qt.ItemDataRole.UserRole + 10)
|
||||||
self.appendRow(item)
|
self.appendRow(item)
|
||||||
|
@ -236,7 +236,7 @@ class OcrQueueModel(QAbstractListModel):
|
|||||||
chart = index.data(self.ChartRole)
|
chart = index.data(self.ChartRole)
|
||||||
score = index.data(self.ScoreRole)
|
score = index.data(self.ScoreRole)
|
||||||
if isinstance(chart, Chart) and isinstance(score, Score):
|
if isinstance(chart, Chart) and isinstance(score, Score):
|
||||||
scoreRange = calculate_score_range(chart.note, score.pure, score.far)
|
scoreRange = calculate_score_range(chart.notes, score.pure, score.far)
|
||||||
scoreValidateOk = scoreRange[0] <= score.score <= scoreRange[1]
|
scoreValidateOk = scoreRange[0] <= score.score <= scoreRange[1]
|
||||||
self.setData(index, scoreValidateOk, self.ScoreValidateOkRole)
|
self.setData(index, scoreValidateOk, self.ScoreValidateOkRole)
|
||||||
else:
|
else:
|
||||||
|
@ -98,7 +98,7 @@ class ChartDelegate(TextSegmentDelegate):
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
self.TextRole: f"{rating_class_to_text(chart.rating_class)} {chart.rating / 10:.1f}",
|
self.TextRole: f"{rating_class_to_text(chart.rating_class)} {chart.constant / 10:.1f}",
|
||||||
self.ColorRole: self.RatingClassColors[chart.rating_class],
|
self.ColorRole: self.RatingClassColors[chart.rating_class],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -95,7 +95,7 @@ class ScoreDelegate(TextSegmentDelegate):
|
|||||||
chart = self.getChart(index)
|
chart = self.getChart(index)
|
||||||
|
|
||||||
if isinstance(score, Score) and isinstance(chart, Chart):
|
if isinstance(score, Score) and isinstance(chart, Chart):
|
||||||
scoreRange = calculate_score_range(chart.note, score.pure, score.far)
|
scoreRange = calculate_score_range(chart.notes, score.pure, score.far)
|
||||||
return scoreRange[0] <= score.score <= scoreRange[1]
|
return scoreRange[0] <= score.score <= scoreRange[1]
|
||||||
|
|
||||||
def getScoreGradeGradientWrapper(self, score: int):
|
def getScoreGradeGradientWrapper(self, score: int):
|
||||||
@ -203,7 +203,7 @@ class ScoreDelegate(TextSegmentDelegate):
|
|||||||
editor.setWindowFlag(Qt.WindowType.Sheet, True)
|
editor.setWindowFlag(Qt.WindowType.Sheet, True)
|
||||||
editor.setWindowFlag(Qt.WindowType.FramelessWindowHint, True)
|
editor.setWindowFlag(Qt.WindowType.FramelessWindowHint, True)
|
||||||
editor.setWindowTitle(
|
editor.setWindowTitle(
|
||||||
f"{chart.name_en}({chart.song_id}) | {rating_class_to_text(chart.rating_class)} | {chart.package_id}"
|
f"{chart.title}({chart.song_id}) | {rating_class_to_text(chart.rating_class)} | {chart.set}"
|
||||||
)
|
)
|
||||||
editor.setText(self.getScore(index))
|
editor.setText(self.getScore(index))
|
||||||
editor.setValidateBeforeAccept(False)
|
editor.setValidateBeforeAccept(False)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from arcaea_offline.database import Database
|
from arcaea_offline.database import Database
|
||||||
from arcaea_offline.models import Chart, Score
|
from arcaea_offline.models import Score
|
||||||
from arcaea_offline_ocr.b30.chieri.v4.ocr import ChieriBotV4Ocr
|
from arcaea_offline_ocr.b30.chieri.v4.ocr import ChieriBotV4Ocr
|
||||||
from arcaea_offline_ocr.b30.shared import B30OcrResultItem
|
from arcaea_offline_ocr.b30.shared import B30OcrResultItem
|
||||||
from PySide6.QtGui import QImage
|
from PySide6.QtGui import QImage
|
||||||
@ -27,25 +27,26 @@ class ChieriV4OcrRunnable(OcrRunnable):
|
|||||||
self.signals.finished.emit()
|
self.signals.finished.emit()
|
||||||
|
|
||||||
|
|
||||||
def b30ResultToScoreInsert(_, qImage: QImage, result: B30OcrResultItem):
|
def b30ResultToScore(_: None, qImage: QImage, result: B30OcrResultItem):
|
||||||
if not result.song_id and not result.title:
|
if not result.song_id and not result.title:
|
||||||
raise ValueError("no title or song_id")
|
raise ValueError("no title or song_id")
|
||||||
|
|
||||||
db = Database()
|
db = Database()
|
||||||
if not result.song_id:
|
if not result.song_id:
|
||||||
song_id = db.fuzzy_search_song_id(result.title)[0][0]
|
raise NotImplementedError("Not supported yet.")
|
||||||
else:
|
else:
|
||||||
song_id = result.song_id
|
song_id = result.song_id
|
||||||
|
|
||||||
chart = Chart.from_db_row(db.get_chart(song_id, result.rating_class))
|
chart = db.get_chart(song_id, result.rating_class)
|
||||||
score = ScoreInsert(
|
score = Score(
|
||||||
song_id=song_id,
|
song_id=song_id,
|
||||||
rating_class=result.rating_class,
|
rating_class=result.rating_class,
|
||||||
score=result.score,
|
score=result.score,
|
||||||
time=1485014400,
|
date=None,
|
||||||
pure=result.pure,
|
pure=result.pure,
|
||||||
far=result.far,
|
far=result.far,
|
||||||
lost=result.lost,
|
lost=result.lost,
|
||||||
|
comment="B30 OCR",
|
||||||
)
|
)
|
||||||
|
|
||||||
return (chart, score)
|
return (chart, score)
|
||||||
|
@ -6,7 +6,7 @@ from arcaea_offline.database import Database
|
|||||||
from arcaea_offline.models import Chart, Score
|
from arcaea_offline.models import Chart, Score
|
||||||
from arcaea_offline_ocr.device.shared import DeviceOcrResult
|
from arcaea_offline_ocr.device.shared import DeviceOcrResult
|
||||||
from arcaea_offline_ocr.device.v2.ocr import DeviceV2Ocr
|
from arcaea_offline_ocr.device.v2.ocr import DeviceV2Ocr
|
||||||
from arcaea_offline_ocr.device.v2.rois import DeviceV2Rois
|
from arcaea_offline_ocr.device.v2.rois import DeviceV2AutoRois, DeviceV2Rois
|
||||||
from arcaea_offline_ocr.utils import imread_unicode
|
from arcaea_offline_ocr.utils import imread_unicode
|
||||||
from PySide6.QtCore import QDateTime, QFileInfo
|
from PySide6.QtCore import QDateTime, QFileInfo
|
||||||
|
|
||||||
@ -37,6 +37,25 @@ class TabDeviceV2OcrRunnable(OcrRunnable):
|
|||||||
self.signals.finished.emit()
|
self.signals.finished.emit()
|
||||||
|
|
||||||
|
|
||||||
|
class TabDeviceV2AutoRoisOcrRunnable(OcrRunnable):
|
||||||
|
def __init__(self, imagePath, knnModel, siftDb):
|
||||||
|
super().__init__()
|
||||||
|
self.imagePath = imagePath
|
||||||
|
self.knnModel = knnModel
|
||||||
|
self.siftDb = siftDb
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
try:
|
||||||
|
rois = DeviceV2AutoRois(imread_unicode(self.imagePath))
|
||||||
|
ocr = DeviceV2Ocr(self.knnModel, self.siftDb)
|
||||||
|
result = ocr.ocr(rois)
|
||||||
|
self.signals.resultReady.emit(result)
|
||||||
|
except Exception:
|
||||||
|
logger.exception(f"DeviceV2AutoRois ocr {self.imagePath} error")
|
||||||
|
finally:
|
||||||
|
self.signals.finished.emit()
|
||||||
|
|
||||||
|
|
||||||
def getImageDate(imagePath: str) -> QDateTime:
|
def getImageDate(imagePath: str) -> QDateTime:
|
||||||
datetime = None
|
datetime = None
|
||||||
with contextlib.suppress(Exception):
|
with contextlib.suppress(Exception):
|
||||||
@ -63,9 +82,7 @@ class ScoreConverter:
|
|||||||
lost=result.lost,
|
lost=result.lost,
|
||||||
date=getImageDate(imagePath).toSecsSinceEpoch(),
|
date=getImageDate(imagePath).toSecsSinceEpoch(),
|
||||||
max_recall=result.max_recall,
|
max_recall=result.max_recall,
|
||||||
r10_clear_type=None,
|
|
||||||
comment=f"OCR {QFileInfo(imagePath).fileName()}",
|
comment=f"OCR {QFileInfo(imagePath).fileName()}",
|
||||||
)
|
)
|
||||||
print(f"OCR {QFileInfo(imagePath).fileName()}")
|
|
||||||
chart = db.get_chart(score.song_id, score.rating_class)
|
chart = db.get_chart(score.song_id, score.rating_class)
|
||||||
return (chart, score)
|
return (chart, score)
|
||||||
|
@ -105,10 +105,10 @@ class ScoreEditor(Ui_ScoreEditor, QWidget):
|
|||||||
|
|
||||||
def setLimits(self, chart: Chart):
|
def setLimits(self, chart: Chart):
|
||||||
self.setMinimums()
|
self.setMinimums()
|
||||||
self.pureSpinBox.setMaximum(chart.note)
|
self.pureSpinBox.setMaximum(chart.notes)
|
||||||
self.farSpinBox.setMaximum(chart.note)
|
self.farSpinBox.setMaximum(chart.notes)
|
||||||
self.lostSpinBox.setMaximum(chart.note)
|
self.lostSpinBox.setMaximum(chart.notes)
|
||||||
self.maxRecallSpinBox.setMaximum(chart.note)
|
self.maxRecallSpinBox.setMaximum(chart.notes)
|
||||||
|
|
||||||
def resetLimits(self):
|
def resetLimits(self):
|
||||||
self.setMinimums()
|
self.setMinimums()
|
||||||
@ -132,9 +132,9 @@ class ScoreEditor(Ui_ScoreEditor, QWidget):
|
|||||||
|
|
||||||
score = self.value()
|
score = self.value()
|
||||||
|
|
||||||
score_range = calculate_score_range(self.__chart.note, score.pure, score.far)
|
score_range = calculate_score_range(self.__chart.notes, score.pure, score.far)
|
||||||
score_in_range = score_range[0] <= score.score <= score_range[1]
|
score_in_range = score_range[0] <= score.score <= score_range[1]
|
||||||
note_in_range = score.pure + score.far + score.lost <= self.__chart.note
|
note_in_range = score.pure + score.far + score.lost <= self.__chart.notes
|
||||||
if not score_in_range or not note_in_range:
|
if not score_in_range or not note_in_range:
|
||||||
return ScoreValidateResult.ScoreMismatch
|
return ScoreValidateResult.ScoreMismatch
|
||||||
if score.score == 0:
|
if score.score == 0:
|
||||||
@ -170,7 +170,6 @@ class ScoreEditor(Ui_ScoreEditor, QWidget):
|
|||||||
max_recall=self.maxRecallSpinBox.value()
|
max_recall=self.maxRecallSpinBox.value()
|
||||||
if self.maxRecallSpinBox.value() > -1
|
if self.maxRecallSpinBox.value() > -1
|
||||||
else None,
|
else None,
|
||||||
r10_clear_type=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def setValue(self, score: Score):
|
def setValue(self, score: Score):
|
||||||
@ -184,8 +183,6 @@ class ScoreEditor(Ui_ScoreEditor, QWidget):
|
|||||||
self.dateTimeEdit.setDateTime(QDateTime.fromSecsSinceEpoch(score.date))
|
self.dateTimeEdit.setDateTime(QDateTime.fromSecsSinceEpoch(score.date))
|
||||||
if score.max_recall is not None:
|
if score.max_recall is not None:
|
||||||
self.maxRecallSpinBox.setValue(score.max_recall)
|
self.maxRecallSpinBox.setValue(score.max_recall)
|
||||||
if score.r10_clear_type is not None:
|
|
||||||
self.clearTypeComboBox.setCurrentIndex(score.r10_clear_type)
|
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.setChart(None)
|
self.setChart(None)
|
||||||
|
@ -14,10 +14,7 @@ from ui.designer.tabs.tabOcr.tabOcr_B30_ui import Ui_TabOcr_B30
|
|||||||
from ui.extends.components.ocrQueue import OcrQueueModel
|
from ui.extends.components.ocrQueue import OcrQueueModel
|
||||||
from ui.extends.shared.cv2_utils import cv2BgrMatToQImage, qImageToCvMatBgr
|
from ui.extends.shared.cv2_utils import cv2BgrMatToQImage, qImageToCvMatBgr
|
||||||
from ui.extends.shared.settings import Settings
|
from ui.extends.shared.settings import Settings
|
||||||
from ui.extends.tabs.tabOcr.tabOcr_B30 import (
|
from ui.extends.tabs.tabOcr.tabOcr_B30 import ChieriV4OcrRunnable, b30ResultToScore
|
||||||
ChieriV4OcrRunnable,
|
|
||||||
b30ResultToScoreInsert,
|
|
||||||
)
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -161,7 +158,7 @@ class TabOcr_B30(Ui_TabOcr_B30, QWidget):
|
|||||||
self.ocrQueueModel.setData(index, runnable, OcrQueueModel.OcrRunnableRole)
|
self.ocrQueueModel.setData(index, runnable, OcrQueueModel.OcrRunnableRole)
|
||||||
self.ocrQueueModel.setData(
|
self.ocrQueueModel.setData(
|
||||||
index,
|
index,
|
||||||
b30ResultToScoreInsert,
|
b30ResultToScore,
|
||||||
OcrQueueModel.ProcessOcrResultFuncRole,
|
OcrQueueModel.ProcessOcrResultFuncRole,
|
||||||
)
|
)
|
||||||
self.ocrQueueModel.startQueue()
|
self.ocrQueueModel.startQueue()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user