-
-
+
- Show OCR Detection Boxes
+ Show Statistics
- OCR
+ OSD
true
@@ -2152,7 +2290,7 @@
0
0
- 901
+ 958
20
diff --git a/src/resizable_rect.py b/src/resizable_rect.py
index c42d210..c6235bc 100644
--- a/src/resizable_rect.py
+++ b/src/resizable_rect.py
@@ -23,6 +23,12 @@ def __init__(self, x, y, width, height, onCenter=False):
self.setPen(QPen(QBrush(Qt.GlobalColor.red), 3))
def getOriginalRect(self):
+ """
+ Retrieve the original rectangle adjusted by the pen width.
+
+ Returns:
+ QRectF: The adjusted rectangle.
+ """
# get the original rect adjusted by the pen width
rect = self.rect()
border = 0 # self.pen().width() / 2
@@ -144,6 +150,23 @@ def hoverMoveEvent(self, event):
super().hoverMoveEvent(event)
+class MiniRect(ResizableRect):
+ def __init__(self, x, y, width, height, parent=None):
+ super().__init__(x, y, width, height)
+ self.setPen(QPen(QColor(255, 0, 0)))
+ self.setBrush(QBrush(QColor(255, 0, 0, 50)))
+ self.setParentItem(parent)
+ self.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable)
+
+ def mousePressEvent(self, event):
+ super().mousePressEvent(event)
+ self.setCursor(Qt.SizeAllCursor)
+
+ def mouseReleaseEvent(self, event):
+ super().mouseReleaseEvent(event)
+ self.unsetCursor()
+
+
class ResizableRectWithNameTypeAndResult(ResizableRect):
def __init__(
self,
@@ -157,7 +180,7 @@ def __init__(
onCenter=False,
boxChangedCallback=None,
itemSelectedCallback=None,
- showOCRRects=True,
+ boxDisplayStyle: int = 1,
):
super().__init__(x, y, width, height, onCenter)
self.setAcceptedMouseButtons(Qt.MouseButton.LeftButton)
@@ -166,20 +189,72 @@ def __init__(
self.result = result
self.boxChangedCallback = boxChangedCallback
self.itemSelectedCallback = itemSelectedCallback
+ self.extraBoxes = []
+ self.cornerBoxes = []
+ self.cornerSize = 20
+
self.posItem = QGraphicsSimpleTextItem("{}".format(self.name), parent=self)
+ self.resultItem = QGraphicsSimpleTextItem("{}".format(self.result), parent=self)
+ self.bgItem = QGraphicsRectItem(self.posItem.boundingRect(), parent=self)
+
+ # Mini-rect related attributes
+ self.mini_rects = []
+ self.mini_rect_mode = False
+ self.add_button = None
+ self.setupAddButton()
+
+ self.setupTextItems(image_size, boxDisplayStyle)
+ self.updateTextLabelPosition()
+ self.setBoxDisplayStyle(boxDisplayStyle)
+ self.setupCornerBoxes()
+ self.updateCornerBoxes()
+
+ def setupAddButton(self):
+ self.add_button = QGraphicsRectItem(0, 0, 60, 30, parent=self)
+ self.add_button.setBrush(QBrush(QColor(0, 255, 0)))
+ self.add_button.setPen(QPen(Qt.black))
+ self.add_button.setPos(self.rect().topLeft() + QPointF(5, 5))
+ self.add_button.setZValue(4)
+ self.add_button.setVisible(False)
+
+ # Add a "+" text to the button
+ text = QGraphicsSimpleTextItem("Add", self.add_button)
+ text.setPos(5, 0)
+ text.setFont(QFont("Arial", 20))
+
+ def setMiniRectMode(self, enabled):
+ self.mini_rect_mode = enabled
+ self.add_button.setVisible(enabled)
+
+ def setupTextItems(self, image_size, boxDisplayStyle):
self.posItem.setBrush(QBrush(QColor("red")))
fontPos = QFont("Arial", int(image_size / 60) if image_size > 0 else 32)
fontPos.setWeight(QFont.Weight.Bold)
self.posItem.setFont(fontPos)
- self.resultItem = QGraphicsSimpleTextItem("{}".format(self.result), parent=self)
self.resultItem.setBrush(QBrush(QColor("red")))
fontRes = QFont("Arial", int(image_size / 75) if image_size > 0 else 20)
fontRes.setWeight(QFont.Weight.Bold)
self.resultItem.setFont(fontRes)
# add a semitraansparent background to the text using another rect
- self.bgItem = QGraphicsRectItem(self.posItem.boundingRect(), parent=self)
self.bgItem.setBrush(QBrush(QColor(0, 0, 0, 128)))
self.bgItem.setPen(QPen(Qt.GlobalColor.transparent))
+ # z order the text over the rect
+ self.posItem.setZValue(2)
+ self.bgItem.setZValue(1)
+ self.effectiveRect = None
+
+ def setupCornerBoxes(self):
+ for i in range(4):
+ cornerBox = QGraphicsRectItem(
+ 0, 0, self.cornerSize, self.cornerSize, parent=self
+ )
+ cornerBox.setBrush(QBrush(QColor(255, 0, 0, 128))) # Light red inside
+ cornerBox.setPen(QPen(QColor("red"))) # Red borders
+ cornerBox.setZValue(3)
+ cornerBox.setVisible(False) # Initially hide the corner boxes
+ self.cornerBoxes.append(cornerBox)
+
+ def updateTextLabelPosition(self):
xpos = (
self.boundingRect().x()
- self.posItem.boundingRect().width() / 2
@@ -189,12 +264,60 @@ def __init__(
# set the text position to the top left corner of the rect
self.posItem.setPos(xpos, ypos)
self.bgItem.setPos(xpos, ypos)
- # z order the text over the rect
- self.posItem.setZValue(2)
- self.bgItem.setZValue(1)
- self.effectiveRect = None
- self.extraBoxes = []
- self.showOCRRects = showOCRRects
+
+ def setBoxDisplayStyle(self, boxDisplayStyle: int):
+ self.boxDisplayStyle = boxDisplayStyle
+ if self.boxDisplayStyle == 0:
+ # hide the rect and the text
+ self.hide()
+ self.posItem.hide()
+ self.bgItem.hide()
+ self.resultItem.hide()
+ elif self.boxDisplayStyle == 1:
+ # show the rect, but not the text
+ self.show()
+ self.posItem.hide()
+ self.bgItem.hide()
+ self.resultItem.hide()
+ else:
+ # show the rect and the text
+ self.show()
+ self.posItem.show()
+ self.bgItem.show()
+ self.resultItem.show()
+
+ if self.boxDisplayStyle != 3:
+ # do not show the effective rect and extra boxes
+ if self.effectiveRect is not None:
+ self.effectiveRect.hide()
+ for extraBox in self.extraBoxes:
+ # remove from the scene
+ extraBox.hide()
+
+ def updateCornerBoxes(self):
+ rect = self.boundingRect()
+ offset = QPointF(self.cornerSize / 2, self.cornerSize / 2)
+ self.cornerBoxes[0].setPos(rect.topLeft() - offset)
+ self.cornerBoxes[1].setPos(rect.topRight() - offset)
+ self.cornerBoxes[2].setPos(rect.bottomLeft() - offset)
+ self.cornerBoxes[3].setPos(rect.bottomRight() - offset)
+
+ def setRect(self, *args, **kwargs):
+ super().setRect(*args, **kwargs)
+ self.updateCornerBoxes()
+ self.updateTextLabelPosition()
+
+ def setSelected(self, selected):
+ super().setSelected(selected)
+ for cornerBox in self.cornerBoxes:
+ cornerBox.setVisible(selected)
+ if selected:
+ self.show()
+ self.posItem.show()
+ self.bgItem.show()
+ self.resultItem.show()
+ else:
+ self.setBoxDisplayStyle(self.boxDisplayStyle)
def getRect(self):
return self.getOriginalRect()
@@ -235,19 +358,8 @@ def updateResult(self, targetWithResult: TextDetectionTargetWithResult):
)
self.resultItem.setZValue(2)
- if not self.showOCRRects:
- # do not show the effective rect and extra boxes
- if self.effectiveRect is not None:
- self.effectiveRect.hide()
- for extraBox in self.extraBoxes:
- # remove from the scene
- extraBox.hide()
- self.scene().removeItem(extraBox)
- self.extraBoxes.clear()
+ if self.boxDisplayStyle != 3:
return
- else:
- if self.effectiveRect is not None:
- self.effectiveRect.show()
if targetWithResult.effectiveRect is not None:
# draw the effective rect in the scene
@@ -294,6 +406,24 @@ def updateResult(self, targetWithResult: TextDetectionTargetWithResult):
extraRect.setZValue(-2)
self.extraBoxes.append(extraRect)
+ def startCreateMiniRect(self, rect: QRectF):
+ new_mini_rect = MiniRect(
+ rect.x(),
+ rect.y(),
+ rect.width(),
+ rect.height(),
+ parent=self,
+ )
+ self.mini_rects.append(new_mini_rect)
+
+ def clearMiniRects(self):
+ for mini_rect in self.mini_rects:
+ self.scene().removeItem(mini_rect)
+ self.mini_rects.clear()
+
+ def getMiniRects(self):
+ return [rect.rect() for rect in self.mini_rects]
+
def mouseReleaseEvent(self, event):
super().mouseReleaseEvent(event)
origRect = self.getRect()
@@ -306,8 +436,30 @@ def mouseReleaseEvent(self, event):
self.boxChangedCallback(self.name, boxRect)
def mousePressEvent(self, event):
- super().mousePressEvent(event)
+ if self.mini_rect_mode:
+ if self.add_button.contains(event.pos()):
+ self.startCreateMiniRect(
+ QRectF(
+ 10,
+ 10,
+ self.getRect().height() * 0.75,
+ self.getRect().width() / 3,
+ )
+ )
+ else:
+ super().mousePressEvent(event)
+ else:
+ super().mousePressEvent(event)
self.itemSelectedCallback(self.name)
def mouseMoveEvent(self, event):
return super().mouseMoveEvent(event)
+
+ def hoverMoveEvent(self, event):
+ super().hoverMoveEvent(event)
+ if self.mini_rect_mode:
+ if self.add_button.contains(event.pos()):
+ self.add_button.setBrush(QBrush(QColor(0, 255, 0, 128)))
+ self.setCursor(Qt.CursorShape.PointingHandCursor)
+ else:
+ self.add_button.setBrush(QBrush(QColor(0, 255, 0)))
diff --git a/src/source_view.py b/src/source_view.py
index 102d64a..344076f 100644
--- a/src/source_view.py
+++ b/src/source_view.py
@@ -13,6 +13,7 @@
fetch_data,
remove_data,
store_data,
+ subscribe_to_data,
)
from text_detection_target import TextDetectionTarget, TextDetectionTargetWithResult
from sc_logging import logger
@@ -63,7 +64,13 @@ def __init__(
self.setFourCorners(fetch_data("scoresight.json", "four_corners"))
self.fourCornersAppliedCallback(self.fourCorners)
self._isScaling = False
- self.showOCRRects = True
+ self._isPanning = False
+ self._lastMousePosition = QPointF()
+
+ self.boxDisplayStyleSetting: int = fetch_data(
+ "scoresight.json", "box_display_style", 3
+ )
+ subscribe_to_data("scoresight.json", "box_display_style", self.boxDisplayStyle)
def resizeEvent(self, event):
if self._isScaling:
@@ -72,11 +79,11 @@ def resizeEvent(self, event):
self.fitInView(self.scene.sceneRect(), Qt.AspectRatioMode.KeepAspectRatio)
self.detectionTargetsChanged()
- def toggleOCRRects(self, state):
- self.showOCRRects = state
+ def boxDisplayStyle(self, state: int):
+ self.boxDisplayStyleSetting = state
for item in self.scene.items():
if isinstance(item, ResizableRectWithNameTypeAndResult):
- item.showOCRRects = state
+ item.setBoxDisplayStyle(state)
def toggleStabilization(self, state):
if self.firstFrameReceived and self.timerThread:
@@ -102,21 +109,20 @@ def detectionTargetsChanged(self):
if not self.firstFrameReceived:
return
- # clear the scene from all ResizableRectWithNameTypeAndResult
- for item in self.scene.items():
- if isinstance(item, ResizableRectWithNameTypeAndResult):
- self.scene.removeItem(item)
# get the detection targets from the storage
detectionTargets: list[TextDetectionTarget] = (
self.detectionTargetsStorage.get_data()
)
+ done_targets = []
# add the boxes to the scene
for detectionTarget in detectionTargets:
+ done_targets.append(detectionTarget.name)
if detectionTarget.settings["templatefield"]:
# do not show the template fields
continue
- self.scene.addItem(
- ResizableRectWithNameTypeAndResult(
+ boxFound = self.findBox(detectionTarget.name)
+ if boxFound is None:
+ boxFound = ResizableRectWithNameTypeAndResult(
detectionTarget.x(),
detectionTarget.y(),
detectionTarget.width(),
@@ -127,9 +133,23 @@ def detectionTargetsChanged(self):
onCenter=False,
boxChangedCallback=self.boxChanged,
itemSelectedCallback=self.itemSelectedCallback,
- showOCRRects=self.showOCRRects,
+ boxDisplayStyle=self.boxDisplayStyleSetting,
)
- )
+ self.scene.addItem(boxFound)
+ else:
+ boxFound.setRect(
+ detectionTarget.x() - boxFound.x(),
+ detectionTarget.y() - boxFound.y(),
+ detectionTarget.width(),
+ detectionTarget.height(),
+ )
+ boxFound.setMiniRectMode(detectionTarget.settings["composite_box"])
+
+ # remove the boxes that are not in the storage
+ for item in self.scene.items():
+ if isinstance(item, ResizableRectWithNameTypeAndResult):
+ if item.name not in done_targets:
+ self.scene.removeItem(item)
def boxChanged(self, name, rect):
# update the detection target in the storage
@@ -161,8 +181,20 @@ def removeBox(self, name):
if item:
self.scene.removeItem(item)
+ def selectBox(self, name):
+ # deselect all the boxes and select the one with the name
+ for item in self.scene.items():
+ if isinstance(item, ResizableRectWithNameTypeAndResult):
+ item.setSelected(item.name == name)
+
def mousePressEvent(self, event: QMouseEvent | None) -> None:
- if self.fourCornerSelectionMode and event.button() == Qt.MouseButton.LeftButton:
+ if event.button() == Qt.MouseButton.MiddleButton:
+ self._isPanning = True
+ self._lastMousePosition = event.position()
+ self.setCursor(Qt.CursorShape.ClosedHandCursor)
+ elif (
+ self.fourCornerSelectionMode and event.button() == Qt.MouseButton.LeftButton
+ ):
# in four corner mode we want to add a point to the scene
# and connect the points in a polygon
# get the position of the click
@@ -201,14 +233,31 @@ def mousePressEvent(self, event: QMouseEvent | None) -> None:
for corner in self.fourCorners:
corner.hide()
else:
+ # deselect all the boxes
+ self.selectBox(None)
+ self.itemSelectedCallback(None)
super().mousePressEvent(event)
def mouseReleaseEvent(self, event: QMouseEvent | None) -> None:
- super().mouseReleaseEvent(event)
- self.detectionTargetsStorage.saveBoxesToStorage()
+ if event.button() == Qt.MouseButton.MiddleButton:
+ self._isPanning = False
+ self.setCursor(Qt.CursorShape.ArrowCursor)
+ else:
+ super().mouseReleaseEvent(event)
+ self.detectionTargetsStorage.saveBoxesToStorage()
def mouseMoveEvent(self, event: QMouseEvent | None) -> None:
- super().mouseMoveEvent(event)
+ if self._isPanning:
+ delta = event.position() - self._lastMousePosition
+ self._lastMousePosition = event.position()
+ self.horizontalScrollBar().setValue(
+ self.horizontalScrollBar().value() - delta.x()
+ )
+ self.verticalScrollBar().setValue(
+ self.verticalScrollBar().value() - delta.y()
+ )
+ else:
+ super().mouseMoveEvent(event)
def wheelEvent(self, event):
# check for ctrl key
diff --git a/src/storage.py b/src/storage.py
index e6b34ec..617c49d 100644
--- a/src/storage.py
+++ b/src/storage.py
@@ -132,11 +132,21 @@ def fetch_custom_box_names():
class TextDetectionTargetMemoryStorage(QObject):
# This class is used to store the text detection targets in memory
+ _instance = None
data_changed = Signal(list)
+ def __new__(cls, *args, **kwargs):
+ if cls._instance is None:
+ cls._instance = super(TextDetectionTargetMemoryStorage, cls).__new__(
+ cls, *args, **kwargs
+ )
+ return cls._instance
+
def __init__(self):
- super().__init__()
- self._data: list[TextDetectionTarget] = []
+ if not hasattr(self, "_initialized"):
+ super().__init__()
+ self._data: list[TextDetectionTarget] = []
+ self._initialized = True
def add_item(self, item: TextDetectionTarget):
self._data.append(item)
@@ -284,6 +294,7 @@ def getBoxesForStorage(self):
"templatefield_text": detectionTarget.settings.get(
"templatefield_text"
),
+ "composite_box": detectionTarget.settings.get("composite_box"),
},
}
)
diff --git a/src/text_detection_target.py b/src/text_detection_target.py
index 451f309..b36a0b0 100644
--- a/src/text_detection_target.py
+++ b/src/text_detection_target.py
@@ -39,7 +39,7 @@ def clear(self):
class TextDetectionTarget(QRectF):
- def __init__(self, x, y, width, height, name: str, settings: dict | None = None):
+ def __init__(self, x, y, width, height, name: str, settings: dict = {}):
super().__init__(x, y, width, height)
self.name = name
self.settings = settings
diff --git a/src/ui_mainwindow.py b/src/ui_mainwindow.py
index f27b34e..84e589a 100644
--- a/src/ui_mainwindow.py
+++ b/src/ui_mainwindow.py
@@ -27,11 +27,11 @@ class Ui_MainWindow(object):
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
- MainWindow.resize(901, 725)
+ MainWindow.resize(958, 730)
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
- self.formLayout = QFormLayout(self.centralwidget)
- self.formLayout.setObjectName(u"formLayout")
+ self.horizontalLayout_31 = QHBoxLayout(self.centralwidget)
+ self.horizontalLayout_31.setObjectName(u"horizontalLayout_31")
self.frame = QFrame(self.centralwidget)
self.frame.setObjectName(u"frame")
sizePolicy = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred)
@@ -73,7 +73,8 @@ def setupUi(self, MainWindow):
self.tableWidget_boxes.setDragDropOverwriteMode(False)
self.tableWidget_boxes.setSelectionMode(QAbstractItemView.SingleSelection)
self.tableWidget_boxes.setShowGrid(False)
- self.tableWidget_boxes.horizontalHeader().setCascadingSectionResizes(True)
+ self.tableWidget_boxes.horizontalHeader().setMinimumSectionSize(134)
+ self.tableWidget_boxes.horizontalHeader().setStretchLastSection(True)
self.tableWidget_boxes.verticalHeader().setVisible(False)
self.horizontalLayout_2.addWidget(self.tableWidget_boxes)
@@ -136,69 +137,74 @@ def setupUi(self, MainWindow):
self.groupBox_target_settings = QGroupBox(self.groupBox_sb_info)
self.groupBox_target_settings.setObjectName(u"groupBox_target_settings")
- self.verticalLayout_5 = QVBoxLayout(self.groupBox_target_settings)
- self.verticalLayout_5.setSpacing(2)
- self.verticalLayout_5.setObjectName(u"verticalLayout_5")
- self.verticalLayout_5.setContentsMargins(3, 0, 3, 3)
- self.widget_10 = QWidget(self.groupBox_target_settings)
- self.widget_10.setObjectName(u"widget_10")
- sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
+ self.gridLayout_6 = QGridLayout(self.groupBox_target_settings)
+ self.gridLayout_6.setObjectName(u"gridLayout_6")
+ self.gridLayout_6.setVerticalSpacing(1)
+ self.gridLayout_6.setContentsMargins(2, 0, 2, 2)
+ self.pushButton_restoreDefaults = QPushButton(self.groupBox_target_settings)
+ self.pushButton_restoreDefaults.setObjectName(u"pushButton_restoreDefaults")
+ sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
sizePolicy2.setHorizontalStretch(0)
sizePolicy2.setVerticalStretch(0)
- sizePolicy2.setHeightForWidth(self.widget_10.sizePolicy().hasHeightForWidth())
- self.widget_10.setSizePolicy(sizePolicy2)
- self.horizontalLayout_12 = QHBoxLayout(self.widget_10)
- self.horizontalLayout_12.setSpacing(3)
- self.horizontalLayout_12.setObjectName(u"horizontalLayout_12")
- self.horizontalLayout_12.setContentsMargins(0, 0, 0, 0)
- self.label_6 = QLabel(self.widget_10)
- self.label_6.setObjectName(u"label_6")
+ sizePolicy2.setHeightForWidth(self.pushButton_restoreDefaults.sizePolicy().hasHeightForWidth())
+ self.pushButton_restoreDefaults.setSizePolicy(sizePolicy2)
- self.horizontalLayout_12.addWidget(self.label_6)
+ self.gridLayout_6.addWidget(self.pushButton_restoreDefaults, 0, 3, 1, 1)
- self.label_selectedInfo = QLabel(self.widget_10)
- self.label_selectedInfo.setObjectName(u"label_selectedInfo")
+ self.checkBox_smoothing = QCheckBox(self.groupBox_target_settings)
+ self.checkBox_smoothing.setObjectName(u"checkBox_smoothing")
- self.horizontalLayout_12.addWidget(self.label_selectedInfo)
+ self.gridLayout_6.addWidget(self.checkBox_smoothing, 3, 2, 1, 1)
- self.horizontalSpacer_3 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
+ self.horizontalLayout_11 = QHBoxLayout()
+ self.horizontalLayout_11.setObjectName(u"horizontalLayout_11")
+ self.label_15 = QLabel(self.groupBox_target_settings)
+ self.label_15.setObjectName(u"label_15")
- self.horizontalLayout_12.addItem(self.horizontalSpacer_3)
+ self.horizontalLayout_11.addWidget(self.label_15)
- self.pushButton_restoreDefaults = QPushButton(self.widget_10)
- self.pushButton_restoreDefaults.setObjectName(u"pushButton_restoreDefaults")
+ self.horizontalSlider_vscale = QSlider(self.groupBox_target_settings)
+ self.horizontalSlider_vscale.setObjectName(u"horizontalSlider_vscale")
+ self.horizontalSlider_vscale.setMinimum(1)
+ self.horizontalSlider_vscale.setMaximum(10)
+ self.horizontalSlider_vscale.setPageStep(5)
+ self.horizontalSlider_vscale.setValue(10)
+ self.horizontalSlider_vscale.setOrientation(Qt.Horizontal)
- self.horizontalLayout_12.addWidget(self.pushButton_restoreDefaults)
+ self.horizontalLayout_11.addWidget(self.horizontalSlider_vscale)
- self.verticalLayout_5.addWidget(self.widget_10)
+ self.gridLayout_6.addLayout(self.horizontalLayout_11, 10, 3, 1, 1)
- self.widget_7 = QWidget(self.groupBox_target_settings)
- self.widget_7.setObjectName(u"widget_7")
- sizePolicy3 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred)
- sizePolicy3.setHorizontalStretch(0)
- sizePolicy3.setVerticalStretch(0)
- sizePolicy3.setHeightForWidth(self.widget_7.sizePolicy().hasHeightForWidth())
- self.widget_7.setSizePolicy(sizePolicy3)
- self.horizontalLayout_8 = QHBoxLayout(self.widget_7)
- self.horizontalLayout_8.setObjectName(u"horizontalLayout_8")
- self.horizontalLayout_8.setContentsMargins(0, 0, 0, 0)
- self.label_2 = QLabel(self.widget_7)
- self.label_2.setObjectName(u"label_2")
+ self.widget_27 = QWidget(self.groupBox_target_settings)
+ self.widget_27.setObjectName(u"widget_27")
+ sizePolicy.setHeightForWidth(self.widget_27.sizePolicy().hasHeightForWidth())
+ self.widget_27.setSizePolicy(sizePolicy)
+ self.horizontalLayout_32 = QHBoxLayout(self.widget_27)
+ self.horizontalLayout_32.setObjectName(u"horizontalLayout_32")
+ self.horizontalLayout_32.setContentsMargins(0, 0, 0, 0)
+ self.label_binarizationMethod = QLabel(self.widget_27)
+ self.label_binarizationMethod.setObjectName(u"label_binarizationMethod")
+ sizePolicy.setHeightForWidth(self.label_binarizationMethod.sizePolicy().hasHeightForWidth())
+ self.label_binarizationMethod.setSizePolicy(sizePolicy)
- self.horizontalLayout_8.addWidget(self.label_2)
+ self.horizontalLayout_32.addWidget(self.label_binarizationMethod)
- self.lineEdit_format = QLineEdit(self.widget_7)
- self.lineEdit_format.setObjectName(u"lineEdit_format")
- sizePolicy4 = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
- sizePolicy4.setHorizontalStretch(0)
- sizePolicy4.setVerticalStretch(0)
- sizePolicy4.setHeightForWidth(self.lineEdit_format.sizePolicy().hasHeightForWidth())
- self.lineEdit_format.setSizePolicy(sizePolicy4)
+ self.comboBox_binarizationMethod = QComboBox(self.widget_27)
+ self.comboBox_binarizationMethod.addItem("")
+ self.comboBox_binarizationMethod.addItem("")
+ self.comboBox_binarizationMethod.addItem("")
+ self.comboBox_binarizationMethod.addItem("")
+ self.comboBox_binarizationMethod.setObjectName(u"comboBox_binarizationMethod")
+ sizePolicy2.setHeightForWidth(self.comboBox_binarizationMethod.sizePolicy().hasHeightForWidth())
+ self.comboBox_binarizationMethod.setSizePolicy(sizePolicy2)
+
+ self.horizontalLayout_32.addWidget(self.comboBox_binarizationMethod)
- self.horizontalLayout_8.addWidget(self.lineEdit_format)
- self.comboBox_formatPrefix = QComboBox(self.widget_7)
+ self.gridLayout_6.addWidget(self.widget_27, 9, 2, 1, 1)
+
+ self.comboBox_formatPrefix = QComboBox(self.groupBox_target_settings)
self.comboBox_formatPrefix.addItem("")
self.comboBox_formatPrefix.addItem("")
self.comboBox_formatPrefix.addItem("")
@@ -213,257 +219,250 @@ def setupUi(self, MainWindow):
self.comboBox_formatPrefix.addItem("")
self.comboBox_formatPrefix.addItem("")
self.comboBox_formatPrefix.setObjectName(u"comboBox_formatPrefix")
- sizePolicy5 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Fixed)
- sizePolicy5.setHorizontalStretch(0)
- sizePolicy5.setVerticalStretch(0)
- sizePolicy5.setHeightForWidth(self.comboBox_formatPrefix.sizePolicy().hasHeightForWidth())
- self.comboBox_formatPrefix.setSizePolicy(sizePolicy5)
+ sizePolicy3 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Fixed)
+ sizePolicy3.setHorizontalStretch(0)
+ sizePolicy3.setVerticalStretch(0)
+ sizePolicy3.setHeightForWidth(self.comboBox_formatPrefix.sizePolicy().hasHeightForWidth())
+ self.comboBox_formatPrefix.setSizePolicy(sizePolicy3)
- self.horizontalLayout_8.addWidget(self.comboBox_formatPrefix)
+ self.gridLayout_6.addWidget(self.comboBox_formatPrefix, 1, 3, 1, 1)
+ self.checkBox_dotDetector = QCheckBox(self.groupBox_target_settings)
+ self.checkBox_dotDetector.setObjectName(u"checkBox_dotDetector")
- self.verticalLayout_5.addWidget(self.widget_7)
+ self.gridLayout_6.addWidget(self.checkBox_dotDetector, 7, 3, 1, 1)
- self.widget_19 = QWidget(self.groupBox_target_settings)
- self.widget_19.setObjectName(u"widget_19")
- self.horizontalLayout_21 = QHBoxLayout(self.widget_19)
- self.horizontalLayout_21.setSpacing(3)
- self.horizontalLayout_21.setObjectName(u"horizontalLayout_21")
- self.horizontalLayout_21.setContentsMargins(0, 0, 0, 0)
- self.label_13 = QLabel(self.widget_19)
+ self.horizontalWidget = QWidget(self.groupBox_target_settings)
+ self.horizontalWidget.setObjectName(u"horizontalWidget")
+ sizePolicy.setHeightForWidth(self.horizontalWidget.sizePolicy().hasHeightForWidth())
+ self.horizontalWidget.setSizePolicy(sizePolicy)
+ self.horizontalLayout_8 = QHBoxLayout(self.horizontalWidget)
+ self.horizontalLayout_8.setObjectName(u"horizontalLayout_8")
+ self.horizontalLayout_8.setContentsMargins(0, 0, 0, 0)
+ self.label_13 = QLabel(self.horizontalWidget)
self.label_13.setObjectName(u"label_13")
+ sizePolicy.setHeightForWidth(self.label_13.sizePolicy().hasHeightForWidth())
+ self.label_13.setSizePolicy(sizePolicy)
- self.horizontalLayout_21.addWidget(self.label_13)
+ self.horizontalLayout_8.addWidget(self.label_13)
- self.comboBox_fieldType = QComboBox(self.widget_19)
+ self.comboBox_fieldType = QComboBox(self.horizontalWidget)
self.comboBox_fieldType.addItem("")
self.comboBox_fieldType.addItem("")
self.comboBox_fieldType.addItem("")
self.comboBox_fieldType.setObjectName(u"comboBox_fieldType")
+ sizePolicy2.setHeightForWidth(self.comboBox_fieldType.sizePolicy().hasHeightForWidth())
+ self.comboBox_fieldType.setSizePolicy(sizePolicy2)
- self.horizontalLayout_21.addWidget(self.comboBox_fieldType)
+ self.horizontalLayout_8.addWidget(self.comboBox_fieldType)
- self.verticalLayout_5.addWidget(self.widget_19)
+ self.gridLayout_6.addWidget(self.horizontalWidget, 2, 2, 1, 1)
- self.widget_14 = QWidget(self.groupBox_target_settings)
- self.widget_14.setObjectName(u"widget_14")
- sizePolicy2.setHeightForWidth(self.widget_14.sizePolicy().hasHeightForWidth())
- self.widget_14.setSizePolicy(sizePolicy2)
- self.horizontalLayout_16 = QHBoxLayout(self.widget_14)
- self.horizontalLayout_16.setSpacing(3)
- self.horizontalLayout_16.setObjectName(u"horizontalLayout_16")
- self.horizontalLayout_16.setContentsMargins(0, 0, 0, 0)
- self.checkBox_smoothing = QCheckBox(self.widget_14)
- self.checkBox_smoothing.setObjectName(u"checkBox_smoothing")
-
- self.horizontalLayout_16.addWidget(self.checkBox_smoothing)
-
- self.checkBox_ordinalIndicator = QCheckBox(self.widget_14)
- self.checkBox_ordinalIndicator.setObjectName(u"checkBox_ordinalIndicator")
+ self.widget_17 = QWidget(self.groupBox_target_settings)
+ self.widget_17.setObjectName(u"widget_17")
+ sizePolicy4 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Preferred)
+ sizePolicy4.setHorizontalStretch(0)
+ sizePolicy4.setVerticalStretch(0)
+ sizePolicy4.setHeightForWidth(self.widget_17.sizePolicy().hasHeightForWidth())
+ self.widget_17.setSizePolicy(sizePolicy4)
+ self.horizontalLayout_15 = QHBoxLayout(self.widget_17)
+ self.horizontalLayout_15.setObjectName(u"horizontalLayout_15")
+ self.horizontalLayout_15.setContentsMargins(0, 0, 0, 0)
+ self.label_4 = QLabel(self.widget_17)
+ self.label_4.setObjectName(u"label_4")
+ sizePolicy.setHeightForWidth(self.label_4.sizePolicy().hasHeightForWidth())
+ self.label_4.setSizePolicy(sizePolicy)
- self.horizontalLayout_16.addWidget(self.checkBox_ordinalIndicator)
+ self.horizontalLayout_15.addWidget(self.label_4)
+ self.horizontalSlider_cleanup = QSlider(self.widget_17)
+ self.horizontalSlider_cleanup.setObjectName(u"horizontalSlider_cleanup")
+ sizePolicy5 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
+ sizePolicy5.setHorizontalStretch(0)
+ sizePolicy5.setVerticalStretch(0)
+ sizePolicy5.setHeightForWidth(self.horizontalSlider_cleanup.sizePolicy().hasHeightForWidth())
+ self.horizontalSlider_cleanup.setSizePolicy(sizePolicy5)
+ self.horizontalSlider_cleanup.setOrientation(Qt.Horizontal)
- self.verticalLayout_5.addWidget(self.widget_14)
+ self.horizontalLayout_15.addWidget(self.horizontalSlider_cleanup)
- self.widget_11 = QWidget(self.groupBox_target_settings)
- self.widget_11.setObjectName(u"widget_11")
- sizePolicy2.setHeightForWidth(self.widget_11.sizePolicy().hasHeightForWidth())
- self.widget_11.setSizePolicy(sizePolicy2)
- self.horizontalLayout_13 = QHBoxLayout(self.widget_11)
- self.horizontalLayout_13.setSpacing(3)
- self.horizontalLayout_13.setObjectName(u"horizontalLayout_13")
- self.horizontalLayout_13.setContentsMargins(0, 0, 0, 0)
- self.checkBox_skip_empty = QCheckBox(self.widget_11)
- self.checkBox_skip_empty.setObjectName(u"checkBox_skip_empty")
- self.horizontalLayout_13.addWidget(self.checkBox_skip_empty)
+ self.gridLayout_6.addWidget(self.widget_17, 10, 2, 1, 1)
- self.checkBox_skip_similar_image = QCheckBox(self.widget_11)
- self.checkBox_skip_similar_image.setObjectName(u"checkBox_skip_similar_image")
+ self.checkBox_ordinalIndicator = QCheckBox(self.groupBox_target_settings)
+ self.checkBox_ordinalIndicator.setObjectName(u"checkBox_ordinalIndicator")
- self.horizontalLayout_13.addWidget(self.checkBox_skip_similar_image)
+ self.gridLayout_6.addWidget(self.checkBox_ordinalIndicator, 3, 3, 1, 1)
+ self.checkBox_skip_empty = QCheckBox(self.groupBox_target_settings)
+ self.checkBox_skip_empty.setObjectName(u"checkBox_skip_empty")
- self.verticalLayout_5.addWidget(self.widget_11)
+ self.gridLayout_6.addWidget(self.checkBox_skip_empty, 4, 2, 1, 1)
- self.widget_15 = QWidget(self.groupBox_target_settings)
- self.widget_15.setObjectName(u"widget_15")
- sizePolicy2.setHeightForWidth(self.widget_15.sizePolicy().hasHeightForWidth())
- self.widget_15.setSizePolicy(sizePolicy2)
- self.horizontalLayout_17 = QHBoxLayout(self.widget_15)
- self.horizontalLayout_17.setSpacing(3)
- self.horizontalLayout_17.setObjectName(u"horizontalLayout_17")
- self.horizontalLayout_17.setContentsMargins(0, 0, 0, 0)
- self.checkBox_autocrop = QCheckBox(self.widget_15)
- self.checkBox_autocrop.setObjectName(u"checkBox_autocrop")
+ self.widget_10 = QWidget(self.groupBox_target_settings)
+ self.widget_10.setObjectName(u"widget_10")
+ sizePolicy4.setHeightForWidth(self.widget_10.sizePolicy().hasHeightForWidth())
+ self.widget_10.setSizePolicy(sizePolicy4)
+ self.horizontalLayout_16 = QHBoxLayout(self.widget_10)
+ self.horizontalLayout_16.setObjectName(u"horizontalLayout_16")
+ self.label_6 = QLabel(self.widget_10)
+ self.label_6.setObjectName(u"label_6")
+ sizePolicy.setHeightForWidth(self.label_6.sizePolicy().hasHeightForWidth())
+ self.label_6.setSizePolicy(sizePolicy)
- self.horizontalLayout_17.addWidget(self.checkBox_autocrop)
+ self.horizontalLayout_16.addWidget(self.label_6)
- self.checkBox_invertPatch = QCheckBox(self.widget_15)
- self.checkBox_invertPatch.setObjectName(u"checkBox_invertPatch")
+ self.label_selectedInfo = QLabel(self.widget_10)
+ self.label_selectedInfo.setObjectName(u"label_selectedInfo")
- self.horizontalLayout_17.addWidget(self.checkBox_invertPatch)
+ self.horizontalLayout_16.addWidget(self.label_selectedInfo)
- self.verticalLayout_5.addWidget(self.widget_15)
+ self.gridLayout_6.addWidget(self.widget_10, 0, 2, 1, 1)
- self.widget_22 = QWidget(self.groupBox_target_settings)
- self.widget_22.setObjectName(u"widget_22")
- self.horizontalLayout_25 = QHBoxLayout(self.widget_22)
- self.horizontalLayout_25.setSpacing(3)
- self.horizontalLayout_25.setObjectName(u"horizontalLayout_25")
- self.horizontalLayout_25.setContentsMargins(0, 0, 0, 0)
- self.checkBox_removeLeadingZeros = QCheckBox(self.widget_22)
- self.checkBox_removeLeadingZeros.setObjectName(u"checkBox_removeLeadingZeros")
+ self.horizontalLayout_12 = QHBoxLayout()
+ self.horizontalLayout_12.setObjectName(u"horizontalLayout_12")
+ self.label_14 = QLabel(self.groupBox_target_settings)
+ self.label_14.setObjectName(u"label_14")
- self.horizontalLayout_25.addWidget(self.checkBox_removeLeadingZeros)
+ self.horizontalLayout_12.addWidget(self.label_14)
- self.checkBox_dotDetector = QCheckBox(self.widget_22)
- self.checkBox_dotDetector.setObjectName(u"checkBox_dotDetector")
+ self.horizontalSlider_skew = QSlider(self.groupBox_target_settings)
+ self.horizontalSlider_skew.setObjectName(u"horizontalSlider_skew")
+ self.horizontalSlider_skew.setMinimum(-10)
+ self.horizontalSlider_skew.setMaximum(10)
+ self.horizontalSlider_skew.setOrientation(Qt.Horizontal)
- self.horizontalLayout_25.addWidget(self.checkBox_dotDetector)
+ self.horizontalLayout_12.addWidget(self.horizontalSlider_skew)
- self.verticalLayout_5.addWidget(self.widget_22)
+ self.gridLayout_6.addLayout(self.horizontalLayout_12, 11, 3, 1, 1)
- self.widget_9 = QWidget(self.groupBox_target_settings)
- self.widget_9.setObjectName(u"widget_9")
- self.horizontalLayout_11 = QHBoxLayout(self.widget_9)
- self.horizontalLayout_11.setSpacing(3)
- self.horizontalLayout_11.setObjectName(u"horizontalLayout_11")
- self.horizontalLayout_11.setContentsMargins(0, 0, 0, 0)
- self.checkBox_rescalePatch = QCheckBox(self.widget_9)
- self.checkBox_rescalePatch.setObjectName(u"checkBox_rescalePatch")
+ self.checkBox_compositeBox = QCheckBox(self.groupBox_target_settings)
+ self.checkBox_compositeBox.setObjectName(u"checkBox_compositeBox")
+ sizePolicy6 = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
+ sizePolicy6.setHorizontalStretch(0)
+ sizePolicy6.setVerticalStretch(0)
+ sizePolicy6.setHeightForWidth(self.checkBox_compositeBox.sizePolicy().hasHeightForWidth())
+ self.checkBox_compositeBox.setSizePolicy(sizePolicy6)
- self.horizontalLayout_11.addWidget(self.checkBox_rescalePatch)
+ self.gridLayout_6.addWidget(self.checkBox_compositeBox, 9, 3, 1, 1)
- self.checkBox_normWHRatio = QCheckBox(self.widget_9)
- self.checkBox_normWHRatio.setObjectName(u"checkBox_normWHRatio")
+ self.widget_21 = QWidget(self.groupBox_target_settings)
+ self.widget_21.setObjectName(u"widget_21")
+ sizePolicy4.setHeightForWidth(self.widget_21.sizePolicy().hasHeightForWidth())
+ self.widget_21.setSizePolicy(sizePolicy4)
+ self.horizontalLayout_20 = QHBoxLayout(self.widget_21)
+ self.horizontalLayout_20.setObjectName(u"horizontalLayout_20")
+ self.horizontalLayout_20.setContentsMargins(0, 0, 0, 0)
+ self.label_3 = QLabel(self.widget_21)
+ self.label_3.setObjectName(u"label_3")
+ sizePolicy.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth())
+ self.label_3.setSizePolicy(sizePolicy)
- self.horizontalLayout_11.addWidget(self.checkBox_normWHRatio)
+ self.horizontalLayout_20.addWidget(self.label_3)
+ self.horizontalSlider_conf_thresh = QSlider(self.widget_21)
+ self.horizontalSlider_conf_thresh.setObjectName(u"horizontalSlider_conf_thresh")
+ sizePolicy5.setHeightForWidth(self.horizontalSlider_conf_thresh.sizePolicy().hasHeightForWidth())
+ self.horizontalSlider_conf_thresh.setSizePolicy(sizePolicy5)
+ self.horizontalSlider_conf_thresh.setValue(50)
+ self.horizontalSlider_conf_thresh.setOrientation(Qt.Horizontal)
- self.verticalLayout_5.addWidget(self.widget_9)
+ self.horizontalLayout_20.addWidget(self.horizontalSlider_conf_thresh)
- self.widget_20 = QWidget(self.groupBox_target_settings)
- self.widget_20.setObjectName(u"widget_20")
- self.horizontalLayout_23 = QHBoxLayout(self.widget_20)
- self.horizontalLayout_23.setSpacing(3)
- self.horizontalLayout_23.setObjectName(u"horizontalLayout_23")
- self.horizontalLayout_23.setContentsMargins(0, 0, 0, 0)
- self.label_binarizationMethod = QLabel(self.widget_20)
- self.label_binarizationMethod.setObjectName(u"label_binarizationMethod")
- self.horizontalLayout_23.addWidget(self.label_binarizationMethod)
+ self.gridLayout_6.addWidget(self.widget_21, 12, 2, 1, 1)
- self.comboBox_binarizationMethod = QComboBox(self.widget_20)
- self.comboBox_binarizationMethod.addItem("")
- self.comboBox_binarizationMethod.addItem("")
- self.comboBox_binarizationMethod.addItem("")
- self.comboBox_binarizationMethod.addItem("")
- self.comboBox_binarizationMethod.setObjectName(u"comboBox_binarizationMethod")
+ self.checkBox_normWHRatio = QCheckBox(self.groupBox_target_settings)
+ self.checkBox_normWHRatio.setObjectName(u"checkBox_normWHRatio")
- self.horizontalLayout_23.addWidget(self.comboBox_binarizationMethod)
+ self.gridLayout_6.addWidget(self.checkBox_normWHRatio, 8, 3, 1, 1)
+ self.checkBox_invertPatch = QCheckBox(self.groupBox_target_settings)
+ self.checkBox_invertPatch.setObjectName(u"checkBox_invertPatch")
- self.verticalLayout_5.addWidget(self.widget_20)
+ self.gridLayout_6.addWidget(self.checkBox_invertPatch, 6, 3, 1, 1)
- self.widget_17 = QWidget(self.groupBox_target_settings)
- self.widget_17.setObjectName(u"widget_17")
- sizePolicy3.setHeightForWidth(self.widget_17.sizePolicy().hasHeightForWidth())
- self.widget_17.setSizePolicy(sizePolicy3)
- self.horizontalLayout_20 = QHBoxLayout(self.widget_17)
- self.horizontalLayout_20.setSpacing(3)
- self.horizontalLayout_20.setObjectName(u"horizontalLayout_20")
- self.horizontalLayout_20.setContentsMargins(0, 0, 0, 0)
- self.label_4 = QLabel(self.widget_17)
- self.label_4.setObjectName(u"label_4")
+ self.checkBox_skip_similar_image = QCheckBox(self.groupBox_target_settings)
+ self.checkBox_skip_similar_image.setObjectName(u"checkBox_skip_similar_image")
- self.horizontalLayout_20.addWidget(self.label_4)
+ self.gridLayout_6.addWidget(self.checkBox_skip_similar_image, 4, 3, 1, 1)
- self.horizontalSlider_cleanup = QSlider(self.widget_17)
- self.horizontalSlider_cleanup.setObjectName(u"horizontalSlider_cleanup")
- self.horizontalSlider_cleanup.setOrientation(Qt.Horizontal)
+ self.checkBox = QCheckBox(self.groupBox_target_settings)
+ self.checkBox.setObjectName(u"checkBox")
+ self.checkBox.setEnabled(False)
+ sizePolicy6.setHeightForWidth(self.checkBox.sizePolicy().hasHeightForWidth())
+ self.checkBox.setSizePolicy(sizePolicy6)
- self.horizontalLayout_20.addWidget(self.horizontalSlider_cleanup)
+ self.gridLayout_6.addWidget(self.checkBox, 2, 3, 1, 1)
- self.label_15 = QLabel(self.widget_17)
- self.label_15.setObjectName(u"label_15")
+ self.widget_7 = QWidget(self.groupBox_target_settings)
+ self.widget_7.setObjectName(u"widget_7")
+ sizePolicy4.setHeightForWidth(self.widget_7.sizePolicy().hasHeightForWidth())
+ self.widget_7.setSizePolicy(sizePolicy4)
+ self.horizontalLayout_17 = QHBoxLayout(self.widget_7)
+ self.horizontalLayout_17.setObjectName(u"horizontalLayout_17")
+ self.horizontalLayout_17.setContentsMargins(0, 0, 0, 0)
+ self.label_2 = QLabel(self.widget_7)
+ self.label_2.setObjectName(u"label_2")
+ sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth())
+ self.label_2.setSizePolicy(sizePolicy)
- self.horizontalLayout_20.addWidget(self.label_15)
+ self.horizontalLayout_17.addWidget(self.label_2)
- self.horizontalSlider_vscale = QSlider(self.widget_17)
- self.horizontalSlider_vscale.setObjectName(u"horizontalSlider_vscale")
- self.horizontalSlider_vscale.setMinimum(1)
- self.horizontalSlider_vscale.setMaximum(10)
- self.horizontalSlider_vscale.setPageStep(5)
- self.horizontalSlider_vscale.setValue(10)
- self.horizontalSlider_vscale.setOrientation(Qt.Horizontal)
+ self.lineEdit_format = QLineEdit(self.widget_7)
+ self.lineEdit_format.setObjectName(u"lineEdit_format")
+ sizePolicy5.setHeightForWidth(self.lineEdit_format.sizePolicy().hasHeightForWidth())
+ self.lineEdit_format.setSizePolicy(sizePolicy5)
- self.horizontalLayout_20.addWidget(self.horizontalSlider_vscale)
+ self.horizontalLayout_17.addWidget(self.lineEdit_format)
- self.verticalLayout_5.addWidget(self.widget_17)
+ self.gridLayout_6.addWidget(self.widget_7, 1, 2, 1, 1)
self.widget_13 = QWidget(self.groupBox_target_settings)
self.widget_13.setObjectName(u"widget_13")
- sizePolicy2.setHeightForWidth(self.widget_13.sizePolicy().hasHeightForWidth())
- self.widget_13.setSizePolicy(sizePolicy2)
- self.horizontalLayout_15 = QHBoxLayout(self.widget_13)
- self.horizontalLayout_15.setSpacing(3)
- self.horizontalLayout_15.setObjectName(u"horizontalLayout_15")
- self.horizontalLayout_15.setContentsMargins(0, 0, 0, 0)
+ sizePolicy4.setHeightForWidth(self.widget_13.sizePolicy().hasHeightForWidth())
+ self.widget_13.setSizePolicy(sizePolicy4)
+ self.horizontalLayout_13 = QHBoxLayout(self.widget_13)
+ self.horizontalLayout_13.setObjectName(u"horizontalLayout_13")
+ self.horizontalLayout_13.setContentsMargins(0, 0, 0, 0)
self.label_9 = QLabel(self.widget_13)
self.label_9.setObjectName(u"label_9")
+ sizePolicy.setHeightForWidth(self.label_9.sizePolicy().hasHeightForWidth())
+ self.label_9.setSizePolicy(sizePolicy)
- self.horizontalLayout_15.addWidget(self.label_9)
+ self.horizontalLayout_13.addWidget(self.label_9)
self.horizontalSlider_dilate = QSlider(self.widget_13)
self.horizontalSlider_dilate.setObjectName(u"horizontalSlider_dilate")
+ sizePolicy5.setHeightForWidth(self.horizontalSlider_dilate.sizePolicy().hasHeightForWidth())
+ self.horizontalSlider_dilate.setSizePolicy(sizePolicy5)
self.horizontalSlider_dilate.setMaximum(5)
self.horizontalSlider_dilate.setPageStep(1)
self.horizontalSlider_dilate.setOrientation(Qt.Horizontal)
- self.horizontalLayout_15.addWidget(self.horizontalSlider_dilate)
-
- self.label_14 = QLabel(self.widget_13)
- self.label_14.setObjectName(u"label_14")
-
- self.horizontalLayout_15.addWidget(self.label_14)
+ self.horizontalLayout_13.addWidget(self.horizontalSlider_dilate)
- self.horizontalSlider_skew = QSlider(self.widget_13)
- self.horizontalSlider_skew.setObjectName(u"horizontalSlider_skew")
- self.horizontalSlider_skew.setMinimum(-10)
- self.horizontalSlider_skew.setMaximum(10)
- self.horizontalSlider_skew.setOrientation(Qt.Horizontal)
- self.horizontalLayout_15.addWidget(self.horizontalSlider_skew)
+ self.gridLayout_6.addWidget(self.widget_13, 11, 2, 1, 1)
+ self.checkBox_autocrop = QCheckBox(self.groupBox_target_settings)
+ self.checkBox_autocrop.setObjectName(u"checkBox_autocrop")
- self.verticalLayout_5.addWidget(self.widget_13)
-
- self.widget_21 = QWidget(self.groupBox_target_settings)
- self.widget_21.setObjectName(u"widget_21")
- self.horizontalLayout_24 = QHBoxLayout(self.widget_21)
- self.horizontalLayout_24.setSpacing(3)
- self.horizontalLayout_24.setObjectName(u"horizontalLayout_24")
- self.horizontalLayout_24.setContentsMargins(0, 0, 0, 0)
- self.label_3 = QLabel(self.widget_21)
- self.label_3.setObjectName(u"label_3")
-
- self.horizontalLayout_24.addWidget(self.label_3)
+ self.gridLayout_6.addWidget(self.checkBox_autocrop, 6, 2, 1, 1)
- self.horizontalSlider_conf_thresh = QSlider(self.widget_21)
- self.horizontalSlider_conf_thresh.setObjectName(u"horizontalSlider_conf_thresh")
- self.horizontalSlider_conf_thresh.setValue(50)
- self.horizontalSlider_conf_thresh.setOrientation(Qt.Horizontal)
+ self.checkBox_removeLeadingZeros = QCheckBox(self.groupBox_target_settings)
+ self.checkBox_removeLeadingZeros.setObjectName(u"checkBox_removeLeadingZeros")
- self.horizontalLayout_24.addWidget(self.horizontalSlider_conf_thresh)
+ self.gridLayout_6.addWidget(self.checkBox_removeLeadingZeros, 7, 2, 1, 1)
+ self.checkBox_rescalePatch = QCheckBox(self.groupBox_target_settings)
+ self.checkBox_rescalePatch.setObjectName(u"checkBox_rescalePatch")
- self.verticalLayout_5.addWidget(self.widget_21)
+ self.gridLayout_6.addWidget(self.checkBox_rescalePatch, 8, 2, 1, 1)
self.verticalLayout_3.addWidget(self.groupBox_target_settings)
@@ -522,10 +521,11 @@ def setupUi(self, MainWindow):
self.tabWidget_outputs.setTabShape(QTabWidget.Rounded)
self.tab_textFiles = QWidget()
self.tab_textFiles.setObjectName(u"tab_textFiles")
- sizePolicy3.setHeightForWidth(self.tab_textFiles.sizePolicy().hasHeightForWidth())
- self.tab_textFiles.setSizePolicy(sizePolicy3)
+ sizePolicy4.setHeightForWidth(self.tab_textFiles.sizePolicy().hasHeightForWidth())
+ self.tab_textFiles.setSizePolicy(sizePolicy4)
self.formLayout_2 = QFormLayout(self.tab_textFiles)
self.formLayout_2.setObjectName(u"formLayout_2")
+ self.formLayout_2.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
self.formLayout_2.setVerticalSpacing(3)
self.formLayout_2.setContentsMargins(-1, -1, -1, 0)
self.label_7 = QLabel(self.tab_textFiles)
@@ -535,8 +535,8 @@ def setupUi(self, MainWindow):
self.widget_5 = QWidget(self.tab_textFiles)
self.widget_5.setObjectName(u"widget_5")
- sizePolicy4.setHeightForWidth(self.widget_5.sizePolicy().hasHeightForWidth())
- self.widget_5.setSizePolicy(sizePolicy4)
+ sizePolicy6.setHeightForWidth(self.widget_5.sizePolicy().hasHeightForWidth())
+ self.widget_5.setSizePolicy(sizePolicy6)
self.horizontalLayout_6 = QHBoxLayout(self.widget_5)
self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0)
@@ -561,8 +561,8 @@ def setupUi(self, MainWindow):
self.widget_12 = QWidget(self.tab_textFiles)
self.widget_12.setObjectName(u"widget_12")
- sizePolicy4.setHeightForWidth(self.widget_12.sizePolicy().hasHeightForWidth())
- self.widget_12.setSizePolicy(sizePolicy4)
+ sizePolicy6.setHeightForWidth(self.widget_12.sizePolicy().hasHeightForWidth())
+ self.widget_12.setSizePolicy(sizePolicy6)
self.horizontalLayout_14 = QHBoxLayout(self.widget_12)
self.horizontalLayout_14.setObjectName(u"horizontalLayout_14")
self.horizontalLayout_14.setContentsMargins(0, 0, 0, 0)
@@ -590,8 +590,8 @@ def setupUi(self, MainWindow):
self.comboBox_appendMethod.addItem("")
self.comboBox_appendMethod.addItem("")
self.comboBox_appendMethod.setObjectName(u"comboBox_appendMethod")
- sizePolicy4.setHeightForWidth(self.comboBox_appendMethod.sizePolicy().hasHeightForWidth())
- self.comboBox_appendMethod.setSizePolicy(sizePolicy4)
+ sizePolicy6.setHeightForWidth(self.comboBox_appendMethod.sizePolicy().hasHeightForWidth())
+ self.comboBox_appendMethod.setSizePolicy(sizePolicy6)
self.formLayout_2.setWidget(2, QFormLayout.FieldRole, self.comboBox_appendMethod)
@@ -611,6 +611,10 @@ def setupUi(self, MainWindow):
self.formLayout_2.setWidget(3, QFormLayout.FieldRole, self.horizontalSlider_aggsPerSecond)
+ self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
+
+ self.formLayout_2.setItem(4, QFormLayout.FieldRole, self.verticalSpacer_2)
+
self.tabWidget_outputs.addTab(self.tab_textFiles, "")
self.tab_browser = QWidget()
self.tab_browser.setObjectName(u"tab_browser")
@@ -632,11 +636,8 @@ def setupUi(self, MainWindow):
self.gridLayout_2.setVerticalSpacing(2)
self.pushButton_connectObs = QPushButton(self.tab_obs)
self.pushButton_connectObs.setObjectName(u"pushButton_connectObs")
- sizePolicy6 = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
- sizePolicy6.setHorizontalStretch(0)
- sizePolicy6.setVerticalStretch(0)
- sizePolicy6.setHeightForWidth(self.pushButton_connectObs.sizePolicy().hasHeightForWidth())
- self.pushButton_connectObs.setSizePolicy(sizePolicy6)
+ sizePolicy5.setHeightForWidth(self.pushButton_connectObs.sizePolicy().hasHeightForWidth())
+ self.pushButton_connectObs.setSizePolicy(sizePolicy5)
self.pushButton_connectObs.setMinimumSize(QSize(0, 0))
self.gridLayout_2.addWidget(self.pushButton_connectObs, 0, 0, 1, 1)
@@ -706,19 +707,16 @@ def setupUi(self, MainWindow):
self.lineEdit_vmixPort = QLineEdit(self.connectionWidget)
self.lineEdit_vmixPort.setObjectName(u"lineEdit_vmixPort")
- sizePolicy7 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
- sizePolicy7.setHorizontalStretch(0)
- sizePolicy7.setVerticalStretch(0)
- sizePolicy7.setHeightForWidth(self.lineEdit_vmixPort.sizePolicy().hasHeightForWidth())
- self.lineEdit_vmixPort.setSizePolicy(sizePolicy7)
+ sizePolicy2.setHeightForWidth(self.lineEdit_vmixPort.sizePolicy().hasHeightForWidth())
+ self.lineEdit_vmixPort.setSizePolicy(sizePolicy2)
self.lineEdit_vmixPort.setMaximumSize(QSize(50, 16777215))
self.horizontalLayout_18.addWidget(self.lineEdit_vmixPort)
self.pushButton_startvmix = QPushButton(self.connectionWidget)
self.pushButton_startvmix.setObjectName(u"pushButton_startvmix")
- sizePolicy7.setHeightForWidth(self.pushButton_startvmix.sizePolicy().hasHeightForWidth())
- self.pushButton_startvmix.setSizePolicy(sizePolicy7)
+ sizePolicy2.setHeightForWidth(self.pushButton_startvmix.sizePolicy().hasHeightForWidth())
+ self.pushButton_startvmix.setSizePolicy(sizePolicy2)
self.pushButton_startvmix.setCheckable(True)
self.pushButton_startvmix.setChecked(False)
@@ -755,11 +753,84 @@ def setupUi(self, MainWindow):
self.gridLayout_3.addLayout(self.verticalLayout_6, 0, 0, 1, 1)
self.tabWidget_outputs.addTab(self.tab_vmix, "")
+ self.tab_uno = QWidget()
+ self.tab_uno.setObjectName(u"tab_uno")
+ self.gridLayout_5 = QGridLayout(self.tab_uno)
+ self.gridLayout_5.setObjectName(u"gridLayout_5")
+ self.verticalLayout_8 = QVBoxLayout()
+ self.verticalLayout_8.setObjectName(u"verticalLayout_8")
+ self.verticalLayout_8.setContentsMargins(0, 0, 0, 0)
+ self.connectionWidget_2 = QWidget(self.tab_uno)
+ self.connectionWidget_2.setObjectName(u"connectionWidget_2")
+ self.horizontalLayout_29 = QHBoxLayout(self.connectionWidget_2)
+ self.horizontalLayout_29.setSpacing(3)
+ self.horizontalLayout_29.setObjectName(u"horizontalLayout_29")
+ self.horizontalLayout_29.setContentsMargins(0, 0, 0, 0)
+ self.connectionLabel_2 = QLabel(self.connectionWidget_2)
+ self.connectionLabel_2.setObjectName(u"connectionLabel_2")
+
+ self.horizontalLayout_29.addWidget(self.connectionLabel_2)
+
+ self.lineEdit_unoUrl = QLineEdit(self.connectionWidget_2)
+ self.lineEdit_unoUrl.setObjectName(u"lineEdit_unoUrl")
+
+ self.horizontalLayout_29.addWidget(self.lineEdit_unoUrl)
+
+ self.toolButton_toggleUno = QToolButton(self.connectionWidget_2)
+ self.toolButton_toggleUno.setObjectName(u"toolButton_toggleUno")
+ self.toolButton_toggleUno.setCheckable(True)
+
+ self.horizontalLayout_29.addWidget(self.toolButton_toggleUno)
+
+
+ self.verticalLayout_8.addWidget(self.connectionWidget_2)
+
+ self.widget_26 = QWidget(self.tab_uno)
+ self.widget_26.setObjectName(u"widget_26")
+ self.widget_26.setMinimumSize(QSize(0, 0))
+ self.horizontalLayout_30 = QHBoxLayout(self.widget_26)
+ self.horizontalLayout_30.setObjectName(u"horizontalLayout_30")
+ self.horizontalLayout_30.setContentsMargins(0, 5, 0, 5)
+ self.checkBox_uno_send_same = QCheckBox(self.widget_26)
+ self.checkBox_uno_send_same.setObjectName(u"checkBox_uno_send_same")
+
+ self.horizontalLayout_30.addWidget(self.checkBox_uno_send_same)
+
+ self.label_23 = QLabel(self.widget_26)
+ self.label_23.setObjectName(u"label_23")
+ sizePolicy.setHeightForWidth(self.label_23.sizePolicy().hasHeightForWidth())
+ self.label_23.setSizePolicy(sizePolicy)
+
+ self.horizontalLayout_30.addWidget(self.label_23)
+
+ self.spinBox = QSpinBox(self.widget_26)
+ self.spinBox.setObjectName(u"spinBox")
+ sizePolicy2.setHeightForWidth(self.spinBox.sizePolicy().hasHeightForWidth())
+ self.spinBox.setSizePolicy(sizePolicy2)
+ self.spinBox.setMinimum(1)
+
+ self.horizontalLayout_30.addWidget(self.spinBox)
+
+
+ self.verticalLayout_8.addWidget(self.widget_26)
+
+
+ self.gridLayout_5.addLayout(self.verticalLayout_8, 0, 0, 1, 1)
+
+ self.tableView_unoMapping = QTableView(self.tab_uno)
+ self.tableView_unoMapping.setObjectName(u"tableView_unoMapping")
+ self.tableView_unoMapping.horizontalHeader().setVisible(False)
+ self.tableView_unoMapping.horizontalHeader().setStretchLastSection(True)
+
+ self.gridLayout_5.addWidget(self.tableView_unoMapping, 1, 0, 1, 1)
+
+ self.tabWidget_outputs.addTab(self.tab_uno, "")
self.tab_api = QWidget()
self.tab_api.setObjectName(u"tab_api")
self.formLayout_3 = QFormLayout(self.tab_api)
self.formLayout_3.setObjectName(u"formLayout_3")
self.formLayout_3.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)
+ self.formLayout_3.setVerticalSpacing(3)
self.checkBox_enableOutAPI = QCheckBox(self.tab_api)
self.checkBox_enableOutAPI.setObjectName(u"checkBox_enableOutAPI")
@@ -856,13 +927,16 @@ def setupUi(self, MainWindow):
self.verticalLayout.addWidget(self.widget_detectionCadence)
- self.formLayout.setWidget(0, QFormLayout.LabelRole, self.frame)
+ self.horizontalLayout_31.addWidget(self.frame)
self.frame_source_view = QFrame(self.centralwidget)
self.frame_source_view.setObjectName(u"frame_source_view")
self.frame_source_view.setEnabled(True)
- sizePolicy2.setHeightForWidth(self.frame_source_view.sizePolicy().hasHeightForWidth())
- self.frame_source_view.setSizePolicy(sizePolicy2)
+ sizePolicy7 = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
+ sizePolicy7.setHorizontalStretch(0)
+ sizePolicy7.setVerticalStretch(0)
+ sizePolicy7.setHeightForWidth(self.frame_source_view.sizePolicy().hasHeightForWidth())
+ self.frame_source_view.setSizePolicy(sizePolicy7)
self.frame_source_view.setFrameShape(QFrame.StyledPanel)
self.frame_source_view.setFrameShadow(QFrame.Raised)
self.verticalLayout_2 = QVBoxLayout(self.frame_source_view)
@@ -969,6 +1043,15 @@ def setupUi(self, MainWindow):
self.horizontalLayout_10.addItem(self.horizontalSpacer_2)
+ self.comboBox_boxDisplayStyle = QComboBox(self.widget_viewTools)
+ self.comboBox_boxDisplayStyle.addItem("")
+ self.comboBox_boxDisplayStyle.addItem("")
+ self.comboBox_boxDisplayStyle.addItem("")
+ self.comboBox_boxDisplayStyle.addItem("")
+ self.comboBox_boxDisplayStyle.setObjectName(u"comboBox_boxDisplayStyle")
+
+ self.horizontalLayout_10.addWidget(self.comboBox_boxDisplayStyle)
+
self.toolButton_osd = QToolButton(self.widget_viewTools)
self.toolButton_osd.setObjectName(u"toolButton_osd")
self.toolButton_osd.setCheckable(True)
@@ -976,13 +1059,6 @@ def setupUi(self, MainWindow):
self.horizontalLayout_10.addWidget(self.toolButton_osd)
- self.toolButton_showOCRrects = QToolButton(self.widget_viewTools)
- self.toolButton_showOCRrects.setObjectName(u"toolButton_showOCRrects")
- self.toolButton_showOCRrects.setCheckable(True)
- self.toolButton_showOCRrects.setChecked(True)
-
- self.horizontalLayout_10.addWidget(self.toolButton_showOCRrects)
-
self.toolButton_zoomReset = QToolButton(self.widget_viewTools)
self.toolButton_zoomReset.setObjectName(u"toolButton_zoomReset")
@@ -1100,18 +1176,18 @@ def setupUi(self, MainWindow):
self.verticalLayout_2.addWidget(self.frame_for_source_view_label)
- self.formLayout.setWidget(0, QFormLayout.FieldRole, self.frame_source_view)
+ self.horizontalLayout_31.addWidget(self.frame_source_view)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QMenuBar(MainWindow)
self.menubar.setObjectName(u"menubar")
- self.menubar.setGeometry(QRect(0, 0, 901, 20))
+ self.menubar.setGeometry(QRect(0, 0, 958, 20))
MainWindow.setMenuBar(self.menubar)
self.retranslateUi(MainWindow)
self.comboBox_formatPrefix.setCurrentIndex(0)
- self.tabWidget_outputs.setCurrentIndex(0)
+ self.tabWidget_outputs.setCurrentIndex(4)
QMetaObject.connectSlotsByName(MainWindow)
@@ -1127,10 +1203,15 @@ def retranslateUi(self, MainWindow):
self.toolButton_removeBox.setText(QCoreApplication.translate("MainWindow", u"-", None))
self.pushButton_makeBox.setText(QCoreApplication.translate("MainWindow", u"Add to Scene ->", None))
self.pushButton_removeBox.setText(QCoreApplication.translate("MainWindow", u"Remove Selected", None))
- self.label_6.setText(QCoreApplication.translate("MainWindow", u"Target:", None))
- self.label_selectedInfo.setText(QCoreApplication.translate("MainWindow", u"Select an item above", None))
self.pushButton_restoreDefaults.setText(QCoreApplication.translate("MainWindow", u"Defaults", None))
- self.label_2.setText(QCoreApplication.translate("MainWindow", u"Format", None))
+ self.checkBox_smoothing.setText(QCoreApplication.translate("MainWindow", u"Average Output", None))
+ self.label_15.setText(QCoreApplication.translate("MainWindow", u"V.Scale", None))
+ self.label_binarizationMethod.setText(QCoreApplication.translate("MainWindow", u"Binarize", None))
+ self.comboBox_binarizationMethod.setItemText(0, QCoreApplication.translate("MainWindow", u"Global", None))
+ self.comboBox_binarizationMethod.setItemText(1, QCoreApplication.translate("MainWindow", u"No Binarization", None))
+ self.comboBox_binarizationMethod.setItemText(2, QCoreApplication.translate("MainWindow", u"Local", None))
+ self.comboBox_binarizationMethod.setItemText(3, QCoreApplication.translate("MainWindow", u"Adaptive", None))
+
self.comboBox_formatPrefix.setItemText(0, QCoreApplication.translate("MainWindow", u"Time mm:ss.d", None))
self.comboBox_formatPrefix.setItemText(1, QCoreApplication.translate("MainWindow", u"Time mm:ss", None))
self.comboBox_formatPrefix.setItemText(2, QCoreApplication.translate("MainWindow", u"Time ss.d", None))
@@ -1145,41 +1226,38 @@ def retranslateUi(self, MainWindow):
self.comboBox_formatPrefix.setItemText(11, QCoreApplication.translate("MainWindow", u"Any number", None))
self.comboBox_formatPrefix.setItemText(12, QCoreApplication.translate("MainWindow", u"Select Preset", None))
+#if QT_CONFIG(tooltip)
+ self.checkBox_dotDetector.setToolTip(QCoreApplication.translate("MainWindow", u"Count dots/blobs instead of detecting characters", None))
+#endif // QT_CONFIG(tooltip)
+ self.checkBox_dotDetector.setText(QCoreApplication.translate("MainWindow", u"Dot Counter", None))
self.label_13.setText(QCoreApplication.translate("MainWindow", u"Type", None))
self.comboBox_fieldType.setItemText(0, QCoreApplication.translate("MainWindow", u"Number 0-9", None))
self.comboBox_fieldType.setItemText(1, QCoreApplication.translate("MainWindow", u"Time 0-9 , . :", None))
self.comboBox_fieldType.setItemText(2, QCoreApplication.translate("MainWindow", u"Text", None))
- self.checkBox_smoothing.setText(QCoreApplication.translate("MainWindow", u"Average Output", None))
+ self.label_4.setText(QCoreApplication.translate("MainWindow", u"Cleanup", None))
self.checkBox_ordinalIndicator.setText(QCoreApplication.translate("MainWindow", u"Ordinal (1st, 2nd, ..)", None))
self.checkBox_skip_empty.setText(QCoreApplication.translate("MainWindow", u"Skip Empty Values", None))
+ self.label_6.setText(QCoreApplication.translate("MainWindow", u"Target:", None))
+ self.label_selectedInfo.setText(QCoreApplication.translate("MainWindow", u"Select an item above", None))
+ self.label_14.setText(QCoreApplication.translate("MainWindow", u"Skew", None))
+ self.checkBox_compositeBox.setText(QCoreApplication.translate("MainWindow", u"Composite (Per-Character)", None))
+ self.label_3.setText(QCoreApplication.translate("MainWindow", u"Conf. Th", None))
+#if QT_CONFIG(tooltip)
+ self.checkBox_normWHRatio.setToolTip(QCoreApplication.translate("MainWindow", u"Scale to a favorable 1:2 width-to-height ratio", None))
+#endif // QT_CONFIG(tooltip)
+ self.checkBox_normWHRatio.setText(QCoreApplication.translate("MainWindow", u"Normalize W-H Ratio", None))
+ self.checkBox_invertPatch.setText(QCoreApplication.translate("MainWindow", u"Invert Input", None))
self.checkBox_skip_similar_image.setText(QCoreApplication.translate("MainWindow", u"Skip Similar Image", None))
+ self.checkBox.setText(QCoreApplication.translate("MainWindow", u"Force Format", None))
+ self.label_2.setText(QCoreApplication.translate("MainWindow", u"Format", None))
+ self.label_9.setText(QCoreApplication.translate("MainWindow", u"Dilate", None))
self.checkBox_autocrop.setText(QCoreApplication.translate("MainWindow", u"Auto Crop", None))
- self.checkBox_invertPatch.setText(QCoreApplication.translate("MainWindow", u"Invert Input", None))
self.checkBox_removeLeadingZeros.setText(QCoreApplication.translate("MainWindow", u"Remove leading 0s", None))
-#if QT_CONFIG(tooltip)
- self.checkBox_dotDetector.setToolTip(QCoreApplication.translate("MainWindow", u"Count dots/blobs instead of detecting characters", None))
-#endif // QT_CONFIG(tooltip)
- self.checkBox_dotDetector.setText(QCoreApplication.translate("MainWindow", u"Dot Counter", None))
#if QT_CONFIG(tooltip)
self.checkBox_rescalePatch.setToolTip(QCoreApplication.translate("MainWindow", u"Scale the image to 35 pixels height, a favorable size for OCR", None))
#endif // QT_CONFIG(tooltip)
self.checkBox_rescalePatch.setText(QCoreApplication.translate("MainWindow", u"Rescale Input", None))
-#if QT_CONFIG(tooltip)
- self.checkBox_normWHRatio.setToolTip(QCoreApplication.translate("MainWindow", u"Scale to a favorable 1:2 width-to-height ratio", None))
-#endif // QT_CONFIG(tooltip)
- self.checkBox_normWHRatio.setText(QCoreApplication.translate("MainWindow", u"Normalize W-H Ratio", None))
- self.label_binarizationMethod.setText(QCoreApplication.translate("MainWindow", u"Binarize", None))
- self.comboBox_binarizationMethod.setItemText(0, QCoreApplication.translate("MainWindow", u"Global", None))
- self.comboBox_binarizationMethod.setItemText(1, QCoreApplication.translate("MainWindow", u"No Binarization", None))
- self.comboBox_binarizationMethod.setItemText(2, QCoreApplication.translate("MainWindow", u"Local", None))
- self.comboBox_binarizationMethod.setItemText(3, QCoreApplication.translate("MainWindow", u"Adaptive", None))
-
- self.label_4.setText(QCoreApplication.translate("MainWindow", u"Cleanup", None))
- self.label_15.setText(QCoreApplication.translate("MainWindow", u"V.Scale", None))
- self.label_9.setText(QCoreApplication.translate("MainWindow", u"Dilate", None))
- self.label_14.setText(QCoreApplication.translate("MainWindow", u"Skew", None))
- self.label_3.setText(QCoreApplication.translate("MainWindow", u"Conf. Th", None))
#if QT_CONFIG(tooltip)
self.checkBox_templatefield.setToolTip(QCoreApplication.translate("MainWindow", u"This field is a combination of exising fields in a template", None))
#endif // QT_CONFIG(tooltip)
@@ -1203,7 +1281,7 @@ def retranslateUi(self, MainWindow):
#endif // QT_CONFIG(tooltip)
self.label_savePerSec.setText(QCoreApplication.translate("MainWindow", u"Save / s", None))
self.tabWidget_outputs.setTabText(self.tabWidget_outputs.indexOf(self.tab_textFiles), QCoreApplication.translate("MainWindow", u"Text Files", None))
- self.label_8.setText(QCoreApplication.translate("MainWindow", u"
HTML Scoreboard: http://localhost:18099/scoresight
JSON: http://localhost:18099/json (optional: ?pivot)
XML: http://localhost:18099/xml (optional: ?pivot)
CSV: http://localhost:18099/csv
", None))
+ self.label_8.setText(QCoreApplication.translate("MainWindow", u"Use these endpoints in external software to get live data updates
HTML Scoreboard: http://localhost:18099/scoresight
JSON: http://localhost:18099/json (optional: ?pivot)
XML: http://localhost:18099/xml (optional: ?pivot)
CSV: http://localhost:18099/csv
", None))
self.tabWidget_outputs.setTabText(self.tabWidget_outputs.indexOf(self.tab_browser), QCoreApplication.translate("MainWindow", u"Browser", None))
self.pushButton_connectObs.setText(QCoreApplication.translate("MainWindow", u"Connect OBS", None))
self.lineEdit_sceneName.setText(QCoreApplication.translate("MainWindow", u"ScoreSight Scene", None))
@@ -1222,6 +1300,16 @@ def retranslateUi(self, MainWindow):
#endif // QT_CONFIG(tooltip)
self.checkBox_vmix_send_same.setText(QCoreApplication.translate("MainWindow", u"Send Same?", None))
self.tabWidget_outputs.setTabText(self.tabWidget_outputs.indexOf(self.tab_vmix), QCoreApplication.translate("MainWindow", u"VMix", None))
+ self.connectionLabel_2.setText(QCoreApplication.translate("MainWindow", u"URL", None))
+ self.lineEdit_unoUrl.setText(QCoreApplication.translate("MainWindow", u"https://app.overlays.uno/apiv2/controlapps/.../api", None))
+ self.toolButton_toggleUno.setText(QCoreApplication.translate("MainWindow", u"\u25b6\ufe0f", None))
+#if QT_CONFIG(tooltip)
+ self.checkBox_uno_send_same.setToolTip(QCoreApplication.translate("MainWindow", u"Send only new detections or also existing?", None))
+#endif // QT_CONFIG(tooltip)
+ self.checkBox_uno_send_same.setText(QCoreApplication.translate("MainWindow", u"Send Same?", None))
+ self.label_23.setText(QCoreApplication.translate("MainWindow", u"Rate Limit", None))
+ self.spinBox.setSuffix(QCoreApplication.translate("MainWindow", u"/second", None))
+ self.tabWidget_outputs.setTabText(self.tabWidget_outputs.indexOf(self.tab_uno), QCoreApplication.translate("MainWindow", u"UNO", None))
self.checkBox_enableOutAPI.setText(QCoreApplication.translate("MainWindow", u"Send out API requests to external services.", None))
self.label_21.setText(QCoreApplication.translate("MainWindow", u"Encode", None))
self.comboBox_api_encode.setItemText(0, QCoreApplication.translate("MainWindow", u"JSON (Full)", None))
@@ -1262,14 +1350,15 @@ def retranslateUi(self, MainWindow):
self.toolButton_topCrop.setText(QCoreApplication.translate("MainWindow", u"Crop", None))
self.toolButton_rotate.setText(QCoreApplication.translate("MainWindow", u"Rotate", None))
self.pushButton_stabilize.setText(QCoreApplication.translate("MainWindow", u"Stabilize", None))
+ self.comboBox_boxDisplayStyle.setItemText(0, QCoreApplication.translate("MainWindow", u"No Box", None))
+ self.comboBox_boxDisplayStyle.setItemText(1, QCoreApplication.translate("MainWindow", u"Outline", None))
+ self.comboBox_boxDisplayStyle.setItemText(2, QCoreApplication.translate("MainWindow", u"Names", None))
+ self.comboBox_boxDisplayStyle.setItemText(3, QCoreApplication.translate("MainWindow", u"All", None))
+
#if QT_CONFIG(tooltip)
self.toolButton_osd.setToolTip(QCoreApplication.translate("MainWindow", u"Show Statistics", None))
#endif // QT_CONFIG(tooltip)
self.toolButton_osd.setText(QCoreApplication.translate("MainWindow", u"OSD", None))
-#if QT_CONFIG(tooltip)
- self.toolButton_showOCRrects.setToolTip(QCoreApplication.translate("MainWindow", u"Show OCR Detection Boxes", None))
-#endif // QT_CONFIG(tooltip)
- self.toolButton_showOCRrects.setText(QCoreApplication.translate("MainWindow", u"OCR", None))
#if QT_CONFIG(tooltip)
self.toolButton_zoomReset.setToolTip(QCoreApplication.translate("MainWindow", u"Reset zoom", None))
#endif // QT_CONFIG(tooltip)
diff --git a/src/uno_output.py b/src/uno_output.py
new file mode 100644
index 0000000..91ae8ff
--- /dev/null
+++ b/src/uno_output.py
@@ -0,0 +1,77 @@
+import requests
+from text_detection_target import TextDetectionTargetWithResult
+from sc_logging import logger
+from storage import subscribe_to_data, fetch_data
+
+
+class UNOAPI:
+ def __init__(self, endpoint, field_mapping):
+ self.endpoint = endpoint
+ self.field_mapping = field_mapping
+ self.running = False
+ self.update_same = fetch_data("scoresight.json", "uno_send_same", False)
+ subscribe_to_data("scoresight.json", "uno_send_same", self.set_update_same)
+
+ def set_update_same(self, update_same):
+ self.update_same = update_same
+
+ def set_field_mapping(self, field_mapping):
+ logger.debug(f"Setting UNO field mapping: {field_mapping}")
+ self.field_mapping = field_mapping
+
+ def update_uno(self, detection: list[TextDetectionTargetWithResult]):
+ if not self.running:
+ return
+
+ if not self.field_mapping:
+ logger.debug("Field mapping is not set")
+ return
+
+ look_in = [TextDetectionTargetWithResult.ResultState.Success]
+ if self.update_same:
+ look_in.append(TextDetectionTargetWithResult.ResultState.SameNoChange)
+
+ for target in detection:
+ if target.result_state in look_in and target.name in self.field_mapping:
+ uno_command = self.field_mapping[target.name]
+ self.send_uno_command(uno_command, target.result)
+
+ def send_uno_command(self, command, value):
+ payload = {"command": command, "value": value}
+
+ try:
+ response = requests.put(self.endpoint, json=payload)
+ if response.status_code != 200:
+ logger.error(
+ f"Failed to send data to UNO API, status code: {response.status_code}"
+ )
+ else:
+ logger.debug(f"Successfully sent {command}: {value} to UNO API")
+
+ # Check rate limit headers
+ self.check_rate_limits(response.headers)
+
+ except requests.exceptions.RequestException as e:
+ logger.error(f"Failed to send data to UNO API: {e}")
+
+ def check_rate_limits(self, headers):
+ rate_limit_headers = [
+ "X-Singular-Ratelimit-Burst-Calls",
+ "X-Singular-Ratelimit-Daily-Calls",
+ "X-Singular-Ratelimit-Burst-Data",
+ "X-Singular-Ratelimit-Daily-Data",
+ ]
+
+ for header in rate_limit_headers:
+ if header in headers:
+ limit_info = headers[header]
+ logger.debug(f"Rate limit info for {header}: {limit_info}")
+
+ # You can add more sophisticated rate limit handling here if needed
+ # For example, pause requests if limits are close to being reached
+
+ def start(self):
+ self.running = True
+
+ def stop(self):
+ self.running = False
diff --git a/src/uno_ui_handler.py b/src/uno_ui_handler.py
new file mode 100644
index 0000000..984f527
--- /dev/null
+++ b/src/uno_ui_handler.py
@@ -0,0 +1,130 @@
+from PySide6.QtGui import QStandardItemModel, QStandardItem
+from PySide6.QtCore import Qt
+
+from text_detection_target import TextDetectionTarget
+from ui_mainwindow import Ui_MainWindow
+from uno_output import UNOAPI
+from sc_logging import logger
+from storage import fetch_data, store_data
+
+standard_uno_mapping = {
+ "Time": "SetMatchTime",
+ "Home Score": "SetGoalsHome",
+ "Away Score": "SetGoalsAway",
+ "Period": "SetPeriod",
+}
+
+
+class UNOUIHandler:
+ def __init__(self, ui: Ui_MainWindow):
+ self.ui = ui
+ self.unoUpdater = None
+ self.unoUiSetup()
+
+ def globalSettingsChanged(self, settingName, value):
+ store_data("scoresight.json", settingName, value)
+
+ def unoConnectionChanged(self):
+ self.unoUpdater = UNOAPI(
+ self.ui.lineEdit_unoUrl.text(),
+ {},
+ )
+ self.globalSettingsChanged("uno_url", self.ui.lineEdit_unoUrl.text())
+ self.unoMappingChanged(True)
+
+ def unoMappingChanged(self, shouldUpdateStorage: bool):
+ mapping = {}
+ model = self.ui.tableView_unoMapping.model()
+ if isinstance(model, QStandardItemModel):
+ for i in range(model.rowCount()):
+ item = model.item(i, 0)
+ value = model.item(i, 1)
+ if item and value:
+ mapping[item.text()] = value.text()
+ if shouldUpdateStorage:
+ self.globalSettingsChanged("uno_mapping", mapping)
+ self.unoUpdater.set_field_mapping(mapping)
+ else:
+ logger.error("unoMappingChanged: model is not a QStandardItemModel")
+
+ def unoUiSetup(self):
+ # populate the UNO connection from storage
+ self.ui.lineEdit_unoUrl.setText(
+ fetch_data(
+ "scoresight.json",
+ "uno_url",
+ "https://app.overlays.uno/apiv2/controlapps/.../api",
+ )
+ )
+ # connect the lineEdit to unoConnectionChanged
+ self.ui.lineEdit_unoUrl.textChanged.connect(self.unoConnectionChanged)
+
+ # create the unoUpdater
+ self.unoUpdater = UNOAPI(
+ self.ui.lineEdit_unoUrl.text(),
+ {},
+ )
+ # add standard item model to the tableView_unoMapping
+ self.ui.tableView_unoMapping.setModel(QStandardItemModel())
+ mapping = fetch_data("scoresight.json", "uno_mapping", {})
+ if mapping:
+ self.unoUpdater.set_field_mapping(mapping)
+
+ self.ui.tableView_unoMapping.model().dataChanged.connect(self.unoMappingChanged)
+
+ self.ui.toolButton_toggleUno.toggled.connect(self.toggleUNO)
+
+ # Connect the "Send Same?" checkbox
+ self.ui.checkBox_uno_send_same.setChecked(
+ fetch_data("scoresight.json", "uno_send_same", False)
+ )
+ self.ui.checkBox_uno_send_same.stateChanged.connect(self.unoSendSameChanged)
+
+ def toggleUNO(self, value):
+ if not self.unoUpdater:
+ return
+ if value:
+ self.ui.toolButton_toggleUno.setText("🛑")
+ self.unoUpdater.start()
+ else:
+ self.ui.toolButton_toggleUno.setText("▶️")
+ self.unoUpdater.stop()
+
+ def unoSendSameChanged(self, state):
+ self.globalSettingsChanged("uno_send_same", state == Qt.Checked)
+
+ def updateUNOTable(self, detectionTargets: list[TextDetectionTarget]):
+ mapping_storage = fetch_data("scoresight.json", "uno_mapping")
+ model = QStandardItemModel()
+ model.blockSignals(True)
+
+ for box in detectionTargets:
+ items = model.findItems(box.name, Qt.MatchFlag.MatchExactly)
+ if len(items) == 0:
+ row = model.rowCount()
+ model.insertRow(row)
+ model.setItem(row, 0, QStandardItem(box.name))
+ model.item(row, 0).setFlags(Qt.ItemFlag.ItemIsEnabled)
+ else:
+ item = items[0]
+ row = item.row()
+
+ new_item_value = None
+ if mapping_storage and box.name in mapping_storage:
+ new_item_value = mapping_storage[box.name]
+ else:
+ if box.name in standard_uno_mapping:
+ new_item_value = standard_uno_mapping[box.name]
+ else:
+ new_item_value = box.name
+ model.setItem(row, 1, QStandardItem(new_item_value))
+
+ for i in range(model.rowCount() - 1, -1, -1):
+ item = model.item(i, 0)
+ if not any([box.name == item.text() for box in detectionTargets]):
+ model.removeRow(i)
+
+ model.blockSignals(False)
+ self.ui.tableView_unoMapping.setModel(model)
+ self.ui.tableView_unoMapping.model().dataChanged.connect(self.unoMappingChanged)
+ self.unoMappingChanged(False)
diff --git a/src/vmix_ui_handler.py b/src/vmix_ui_handler.py
new file mode 100644
index 0000000..8c9c059
--- /dev/null
+++ b/src/vmix_ui_handler.py
@@ -0,0 +1,127 @@
+from PySide6.QtGui import QStandardItemModel, QStandardItem
+from PySide6.QtCore import Qt
+
+from text_detection_target import TextDetectionTarget
+from ui_mainwindow import Ui_MainWindow
+from vmix_output import VMixAPI
+from sc_logging import logger
+from storage import fetch_data, store_data
+
+
+class VMixUIHanlder:
+ def __init__(self, ui: Ui_MainWindow):
+ self.ui = ui
+ self.vmixUpdater = None
+ self.vmixUiSetup()
+
+ def globalSettingsChanged(self, settingName, value):
+ store_data("scoresight.json", settingName, value)
+
+ def vmixConnectionChanged(self):
+ self.vmixUpdater = VMixAPI(
+ self.ui.lineEdit_vmixHost.text(),
+ self.ui.lineEdit_vmixPort.text(),
+ self.ui.inputLineEdit_vmix.text(),
+ {},
+ )
+ self.globalSettingsChanged("vmix_host", self.ui.lineEdit_vmixHost.text())
+ self.globalSettingsChanged("vmix_port", self.ui.lineEdit_vmixPort.text())
+ self.globalSettingsChanged("vmix_input", self.ui.inputLineEdit_vmix.text())
+
+ def vmixMappingChanged(self, _):
+ # store entire mapping data in scoresight.json
+ mapping = {}
+ model = self.ui.tableView_vmixMapping.model()
+ if isinstance(model, QStandardItemModel):
+ for i in range(model.rowCount()):
+ item = model.item(i, 0)
+ value = model.item(i, 1)
+ if item and value:
+ mapping[item.text()] = value.text()
+ self.globalSettingsChanged("vmix_mapping", mapping)
+ self.vmixUpdater.set_field_mapping(mapping)
+ else:
+ logger.error("vmixMappingChanged: model is not a QStandardItemModel")
+
+ def vmixUiSetup(self):
+ # populate the vmix connection from storage
+ self.ui.lineEdit_vmixHost.setText(
+ fetch_data("scoresight.json", "vmix_host", "localhost")
+ )
+ self.ui.lineEdit_vmixPort.setText(
+ fetch_data("scoresight.json", "vmix_port", "8099")
+ )
+ self.ui.inputLineEdit_vmix.setText(
+ fetch_data("scoresight.json", "vmix_input", "1")
+ )
+ # connect the lineEdits to vmixConnectionChanged
+ self.ui.lineEdit_vmixHost.textChanged.connect(self.vmixConnectionChanged)
+ self.ui.lineEdit_vmixPort.textChanged.connect(self.vmixConnectionChanged)
+ self.ui.inputLineEdit_vmix.textChanged.connect(self.vmixConnectionChanged)
+
+ # create the vmixUpdater
+ self.vmixUpdater = VMixAPI(
+ self.ui.lineEdit_vmixHost.text(),
+ self.ui.lineEdit_vmixPort.text(),
+ self.ui.inputLineEdit_vmix.text(),
+ {},
+ )
+ # add standard item model to the tableView_vmixMapping
+ self.ui.tableView_vmixMapping.setModel(QStandardItemModel())
+ mapping = fetch_data("scoresight.json", "vmix_mapping", {})
+ if mapping:
+ self.vmixUpdater.set_field_mapping(mapping)
+
+ self.ui.tableView_vmixMapping.model().dataChanged.connect(
+ self.vmixMappingChanged
+ )
+
+ self.ui.pushButton_startvmix.toggled.connect(self.togglevMix)
+
+ def togglevMix(self, value):
+ if not self.vmixUpdater:
+ return
+ if value:
+ self.ui.pushButton_startvmix.setText("🛑 Stop vMix")
+ self.vmixUpdater.running = True
+ else:
+ self.ui.pushButton_startvmix.setText("▶️ Start vMix")
+ self.vmixUpdater.running = False
+
+ def updatevMixTable(self, detectionTargets: list[TextDetectionTarget]):
+ mapping_storage = fetch_data("scoresight.json", "vmix_mapping")
+ model = QStandardItemModel()
+ model.blockSignals(True)
+
+ for box in detectionTargets:
+ # add the detection to the vmix output mapping: tableView_vmixMapping
+ # check if the table already has the detectionTarget
+ items = model.findItems(box.name, Qt.MatchFlag.MatchExactly)
+ if len(items) == 0:
+ # add the item to the list
+ row = model.rowCount()
+ model.insertRow(row)
+ model.setItem(row, 0, QStandardItem(box.name))
+ # the first item shouldn't be editable
+ model.item(row, 0).setFlags(Qt.ItemFlag.NoItemFlags)
+ else:
+ # update the item in the list
+ item = items[0]
+ row = item.row()
+
+ # get value from storage or use the box name
+ if mapping_storage and box.name in mapping_storage:
+ model.setItem(row, 1, QStandardItem(mapping_storage[box.name]))
+ else:
+ model.setItem(row, 1, QStandardItem(box.name))
+ # remove the items that are not in the detectionTargets
+ for i in range(model.rowCount()):
+ item = model.item(i, 0)
+ if not any([box.name == item.text() for box in detectionTargets]):
+ model.removeRow(i)
+
+ model.blockSignals(False)
+ self.ui.tableView_vmixMapping.setModel(model)
+ self.ui.tableView_vmixMapping.model().dataChanged.connect(
+ self.vmixMappingChanged
+ )