wip
This commit is contained in:
parent
df3be4c784
commit
304fd9d664
@ -44,7 +44,4 @@ port: COM1
|
|||||||
baudrate: 9600
|
baudrate: 9600
|
||||||
|
|
||||||
[vision]
|
[vision]
|
||||||
detection_threshold: 0.5
|
|
||||||
neural_network: hs5-20000
|
neural_network: hs5-20000
|
||||||
|
|
||||||
; recipes_path: ./config/vision_test_recipes
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ instruction: CONTROLLARE PRESENZA TERMORESTRINGENTE
|
|||||||
[markers]
|
[markers]
|
||||||
|
|
||||||
[zones]
|
[zones]
|
||||||
p1: 1000,500 800,800 hs-ok # HEATSINK PRESENT
|
p1: 1200,600 1800,1200 hs-ok # HEATSINK PRESENT
|
||||||
|
|
||||||
[labels]
|
[labels]
|
||||||
p1: 660,1200 120 0xffffffff 0xff000000 4 TERMORESTRINGENTE
|
p1: 660,1200 120 0xffffffff 0xff000000 4 TERMORESTRINGENTE
|
||||||
|
|||||||
@ -31,6 +31,7 @@ $* 2> >(sed $'s/.*/\e[31m&\e[m/' >&2) # &
|
|||||||
# --auto-login-user \
|
# --auto-login-user \
|
||||||
# --autotests-archive \
|
# --autotests-archive \
|
||||||
# --camera-edits \
|
# --camera-edits \
|
||||||
|
# --fail-vision \
|
||||||
# --full-screen \
|
# --full-screen \
|
||||||
# --interact \
|
# --interact \
|
||||||
# --maximized \
|
# --maximized \
|
||||||
|
|||||||
@ -49,7 +49,7 @@ registers = {
|
|||||||
180: "END SEQUENCE PROGRAM",
|
180: "END SEQUENCE PROGRAM",
|
||||||
190: "END PLUG",
|
190: "END PLUG",
|
||||||
200: "END CAGE",
|
200: "END CAGE",
|
||||||
210: "FINE TEST", # WAITING THE START OF A NEW TEST",
|
210: "FINE TEST", # "WAITING THE START OF A NEW TEST",
|
||||||
}, }],
|
}, }],
|
||||||
"Running test: phase backwards time": [33 - 1, {"dt": "16bit_uint", "f": 26, }],
|
"Running test: phase backwards time": [33 - 1, {"dt": "16bit_uint", "f": 26, }],
|
||||||
"Running test: filling pressure": [34 - 1, {"dt": "32bit_int", "f": 21, }],
|
"Running test: filling pressure": [34 - 1, {"dt": "32bit_int", "f": 21, }],
|
||||||
|
|||||||
@ -47,6 +47,11 @@ else:
|
|||||||
def Interpreter(*args, **kwargs):
|
def Interpreter(*args, **kwargs):
|
||||||
raise ValueError("\"--no-tflite\" in sys.argv")
|
raise ValueError("\"--no-tflite\" in sys.argv")
|
||||||
|
|
||||||
|
if "--fail-vision" not in sys.argv:
|
||||||
|
vision_override = None
|
||||||
|
else:
|
||||||
|
vision_override = False
|
||||||
|
|
||||||
# # Patch the location of gfile
|
# # Patch the location of gfile
|
||||||
# tf.gfile = tf.io.gfile
|
# tf.gfile = tf.io.gfile
|
||||||
|
|
||||||
@ -95,7 +100,7 @@ class Vision(Component):
|
|||||||
|
|
||||||
def config_changed(self):
|
def config_changed(self):
|
||||||
# OBJECT DETECTION
|
# OBJECT DETECTION
|
||||||
self.detection_threshold = float(self.config[self.name]["detection_threshold"])
|
self.detection_threshold = float(self.config[self.name].get("detection_threshold", 0.5))
|
||||||
# recipe
|
# recipe
|
||||||
self.zones = None
|
self.zones = None
|
||||||
self.labels = None
|
self.labels = None
|
||||||
@ -122,20 +127,26 @@ class Vision(Component):
|
|||||||
self.num_classes = len(label_map.item)
|
self.num_classes = len(label_map.item)
|
||||||
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=self.num_classes, use_display_name=True)
|
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=self.num_classes, use_display_name=True)
|
||||||
self.category_index = label_map_util.create_category_index(categories)
|
self.category_index = label_map_util.create_category_index(categories)
|
||||||
|
for k in self.category_index:
|
||||||
|
self.category_index[k]["color"] = self.category_index[k]["color"].replace("0x", "#")
|
||||||
self.classes_map = {c["name"]: k for k, c in self.category_index.items()}
|
self.classes_map = {c["name"]: k for k, c in self.category_index.items()}
|
||||||
self.zone_detection_filter_mode = self.config[self.name].get("zone_detection_filter_mode", "box_touches")
|
self.zone_detection_filter_mode = self.config[self.name].get("zone_detection_filter_mode", "box_inside")
|
||||||
self.zone_detection_preference_mode = self.config[self.name].get("zone_detection_preference_mode", "distance")
|
self.zone_detection_preference_mode = self.config[self.name].get("zone_detection_preference_mode", "score")
|
||||||
|
|
||||||
def get_center(self, rect):
|
@staticmethod
|
||||||
|
def get_center(rect):
|
||||||
return [(rect[0] + rect[2]) / 2, (rect[1] + rect[3]) / 2]
|
return [(rect[0] + rect[2]) / 2, (rect[1] + rect[3]) / 2]
|
||||||
|
|
||||||
def get_size(self, rect):
|
@staticmethod
|
||||||
|
def get_size(rect):
|
||||||
return [rect[2] - rect[0], rect[3] - rect[1]]
|
return [rect[2] - rect[0], rect[3] - rect[1]]
|
||||||
|
|
||||||
def get_box(self, center, size):
|
@staticmethod
|
||||||
|
def get_box(center, size):
|
||||||
return [center[0] - size[0] / 2, center[1] - size[1] / 2, center[0] + size[0] / 2, center[1] + size[1] / 2]
|
return [center[0] - size[0] / 2, center[1] - size[1] / 2, center[0] + size[0] / 2, center[1] + size[1] / 2]
|
||||||
|
|
||||||
def get_distance(self, p1, p2):
|
@staticmethod
|
||||||
|
def get_distance(p1, p2):
|
||||||
return pow((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2, 1 / 2)
|
return pow((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2, 1 / 2)
|
||||||
|
|
||||||
def clear_recipe(self):
|
def clear_recipe(self):
|
||||||
@ -180,6 +191,7 @@ class Vision(Component):
|
|||||||
if recipe is None:
|
if recipe is None:
|
||||||
self.clear_recipe()
|
self.clear_recipe()
|
||||||
else:
|
else:
|
||||||
|
self.recipe = recipe
|
||||||
self._set_recipe(self.recipes_dir / str(recipe))
|
self._set_recipe(self.recipes_dir / str(recipe))
|
||||||
|
|
||||||
def parse_markers(self, config=None):
|
def parse_markers(self, config=None):
|
||||||
@ -229,9 +241,10 @@ class Vision(Component):
|
|||||||
shape = "ellipse"
|
shape = "ellipse"
|
||||||
d_class = self.category_index[self.classes_map[d_class]]
|
d_class = self.category_index[self.classes_map[d_class]]
|
||||||
zones[zone_name] = {
|
zones[zone_name] = {
|
||||||
"border_color": QColor(d_class["color"].replace("0x", "#")),
|
"border_color": QColor(d_class["color"]),
|
||||||
"border_thickness": 25,
|
"border_thickness": 25,
|
||||||
"box": self.get_box(center, size),
|
"box": self.get_box(center, size),
|
||||||
|
"convert_negative_placement": False,
|
||||||
"center": center,
|
"center": center,
|
||||||
"class": d_class,
|
"class": d_class,
|
||||||
"fill_color": QColor("#00000000"),
|
"fill_color": QColor("#00000000"),
|
||||||
@ -426,22 +439,23 @@ class Vision(Component):
|
|||||||
style = {
|
style = {
|
||||||
"border_thickness": 25,
|
"border_thickness": 25,
|
||||||
"fill_color": QColor("#00000000"),
|
"fill_color": QColor("#00000000"),
|
||||||
"shape": "ellipse",
|
"shape": "rect",
|
||||||
|
"convert_negative_placement": False,
|
||||||
}
|
}
|
||||||
items = {}
|
items = {}
|
||||||
for item_name, item in enumerate(detections):
|
for item_name, item in enumerate(detections):
|
||||||
items[str(item_name)] = {
|
items[str(item_name)] = {
|
||||||
"box": item["box"],
|
**item,
|
||||||
**style,
|
**style,
|
||||||
"border_color": QColor(item["class"]["color"].replace("0x", "#")),
|
"border_color": QColor(item["class"]["color"]),
|
||||||
}
|
}
|
||||||
return items
|
return items
|
||||||
else:
|
else:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def process_detections(self, detections):
|
def process_detections(self, detections):
|
||||||
if self.zones is None or not len(self.zones) or detections is None or not len(detections):
|
if self.zones is None or not len(self.zones):
|
||||||
return {}
|
return None
|
||||||
# MATCH DETECTIONS WITH RECIPE
|
# MATCH DETECTIONS WITH RECIPE
|
||||||
results = dict.fromkeys(self.zones)
|
results = dict.fromkeys(self.zones)
|
||||||
for detection in detections:
|
for detection in detections:
|
||||||
@ -533,8 +547,13 @@ class Vision(Component):
|
|||||||
"expected": expected_class,
|
"expected": expected_class,
|
||||||
"detection": detection,
|
"detection": detection,
|
||||||
}
|
}
|
||||||
|
global vision_override
|
||||||
|
if vision_override is None:
|
||||||
|
ok = all(map(lambda detection: detection["ok"] is True, checked.values()))
|
||||||
|
else:
|
||||||
|
ok = vision_override
|
||||||
return {
|
return {
|
||||||
"ok": all(map(lambda detection: detection["ok"] is True, checked.values())),
|
"ok": ok,
|
||||||
"results": checked,
|
"results": checked,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,6 +561,7 @@ class Vision(Component):
|
|||||||
# DRAW ZONES RESULTS
|
# DRAW ZONES RESULTS
|
||||||
if self.zones is not None and len(self.zones) and results is not None and len(results):
|
if self.zones is not None and len(self.zones) and results is not None and len(results):
|
||||||
style = {
|
style = {
|
||||||
|
"pen_line": "SolidLine",
|
||||||
"border_thickness": 50,
|
"border_thickness": 50,
|
||||||
"fill_color": QColor("#00000000"),
|
"fill_color": QColor("#00000000"),
|
||||||
}
|
}
|
||||||
@ -561,9 +581,7 @@ class Vision(Component):
|
|||||||
for item_name, item in results["results"].items():
|
for item_name, item in results["results"].items():
|
||||||
zone = self.zones[item_name]
|
zone = self.zones[item_name]
|
||||||
items[str(item_name)] = {
|
items[str(item_name)] = {
|
||||||
"center": zone["center"],
|
**zone,
|
||||||
"size": zone["size"],
|
|
||||||
"shape": zone["shape"],
|
|
||||||
**style,
|
**style,
|
||||||
"border_color": Qt.green if item["ok"] else Qt.red,
|
"border_color": Qt.green if item["ok"] else Qt.red,
|
||||||
}
|
}
|
||||||
@ -571,9 +589,30 @@ class Vision(Component):
|
|||||||
else:
|
else:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def convert_negative_placement(p, painter):
|
||||||
|
for k in p:
|
||||||
|
if p[k] < 0:
|
||||||
|
if k.startswith("x") or k.startswith("w"):
|
||||||
|
p[k] += painter.device().width()
|
||||||
|
elif k.startswith("y") or k.startswith("h"):
|
||||||
|
p[k] += painter.device().height()
|
||||||
|
else:
|
||||||
|
raise AssertionError("could not detect variable direction")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def apply_placement_offset(p, offset):
|
||||||
|
for k in p:
|
||||||
|
if k.startswith("x"):
|
||||||
|
p[k] += offset["x"]
|
||||||
|
elif k.startswith("y"):
|
||||||
|
p[k] += offset["y"]
|
||||||
|
else:
|
||||||
|
raise AssertionError("could not detect variable direction")
|
||||||
|
|
||||||
def render_items(self, items, offset=None, qimage=None, painter=None):
|
def render_items(self, items, offset=None, qimage=None, painter=None):
|
||||||
if offset is None:
|
if offset is None:
|
||||||
offset = [0, 0]
|
offset = {"x": 0, "y": 0}
|
||||||
if painter is None:
|
if painter is None:
|
||||||
if qimage is None:
|
if qimage is None:
|
||||||
raise AssertionError("one of 'qimage' or 'painter' parameter must not be None")
|
raise AssertionError("one of 'qimage' or 'painter' parameter must not be None")
|
||||||
@ -581,35 +620,36 @@ class Vision(Component):
|
|||||||
painter.begin(qimage)
|
painter.begin(qimage)
|
||||||
for item_name, item in items.items():
|
for item_name, item in items.items():
|
||||||
try:
|
try:
|
||||||
v = {}
|
convert_negative_placement = item.get("convert_negative_placement", True)
|
||||||
if "box" in item:
|
if "box" in item:
|
||||||
v["x1"], v["y1"], v["x2"], v["y2"] = item["box"][1] + offset[1], item["box"][0] + offset[0], item["box"][3] + offset[1], item["box"][2] + offset[0]
|
p = {"x1": item["box"][1], "y1": item["box"][0], "x2": item["box"][3], "y2": item["box"][2], }
|
||||||
v["w"], v["h"] = v["x2"] - v["x1"], v["y2"] - v["y1"]
|
if convert_negative_placement:
|
||||||
v["xc"], v["yc"] = self.get_center([v["x1"], v["y1"], v["x2"], v["y2"]])
|
Vision.convert_negative_placement(p, painter)
|
||||||
|
Vision.apply_placement_offset(p, offset)
|
||||||
|
p["w"], p["h"] = p["x2"] - p["x1"], p["y2"] - p["y1"]
|
||||||
|
p["xc"], p["yc"] = Vision.get_center([p["x1"], p["y1"], p["x2"], p["y2"]])
|
||||||
elif "location" in item:
|
elif "location" in item:
|
||||||
v["x1"], v["y1"] = item["location"][1] + offset[1], item["location"][0] + offset[0]
|
p = {"x1": item["location"][1], "y1": item["location"][0], }
|
||||||
|
if convert_negative_placement:
|
||||||
|
Vision.convert_negative_placement(p, painter)
|
||||||
|
Vision.apply_placement_offset(p, offset)
|
||||||
if "size" in item:
|
if "size" in item:
|
||||||
v["w"], v["h"] = item["size"][1], item["size"][0]
|
p["w"], p["h"] = item["size"][1], item["size"][0]
|
||||||
v["x2"], v["y2"] = v["x1"] + v["w"], v["y1"] + v["h"]
|
p["x2"], p["y2"] = p["x1"] + p["w"], p["y1"] + p["h"]
|
||||||
v["xc"], v["yc"] = self.get_center([v["x1"], v["y1"], v["x2"], v["y2"]])
|
p["xc"], p["yc"] = Vision.get_center([p["x1"], p["y1"], p["x2"], p["y2"]])
|
||||||
else:
|
else:
|
||||||
v["w"], v["h"] = 0, 0
|
p["w"], p["h"] = 0, 0
|
||||||
v["x2"], v["y2"] = v["x1"], v["y1"]
|
p["x2"], p["y2"] = p["x1"], p["y1"]
|
||||||
v["xc"], v["yc"] = v["x1"], v["y1"]
|
p["xc"], p["yc"] = p["x1"], p["y1"]
|
||||||
elif "center" in item and "size" in item:
|
elif "center" in item and "size" in item:
|
||||||
v["xc"], v["yc"] = item["center"][1] + offset[1], item["center"][0] + offset[0]
|
p = {"xc": item["center"][1], "yc": item["center"][0], }
|
||||||
v["w"], v["h"] = item["size"][1], item["size"][0]
|
if convert_negative_placement:
|
||||||
v["x1"], v["y1"], v["x2"], v["y2"] = self.get_box([v["xc"], v["yc"]], [v["w"], v["h"]])
|
Vision.convert_negative_placement(p, painter)
|
||||||
|
Vision.apply_placement_offset(p, offset)
|
||||||
|
p["w"], p["h"] = item["size"][1], item["size"][0]
|
||||||
|
p["x1"], p["y1"], p["x2"], p["y2"] = Vision.get_box([p["xc"], p["yc"]], [p["w"], p["h"]])
|
||||||
else:
|
else:
|
||||||
raise AssertionError("item has no valid positioning information")
|
raise AssertionError("item has no valid positioning information")
|
||||||
for k in list(v):
|
|
||||||
if v[k] < 0:
|
|
||||||
if k.startswith("x") or k.startswith("w"):
|
|
||||||
v[k] = painter.device().width() + v[k]
|
|
||||||
elif k.startswith("y") or k.startswith("h"):
|
|
||||||
v[k] = painter.device().height() + v[k]
|
|
||||||
else:
|
|
||||||
raise AssertionError("could not detect variable direction")
|
|
||||||
painter.setOpacity(item.get("opacity", 0.5))
|
painter.setOpacity(item.get("opacity", 0.5))
|
||||||
painter.setBrush(QBrush(item.get("fill_color", QColor("#ffffff")), getattr(Qt, item.get("brush_pattern", "SolidPattern"))))
|
painter.setBrush(QBrush(item.get("fill_color", QColor("#ffffff")), getattr(Qt, item.get("brush_pattern", "SolidPattern"))))
|
||||||
painter.setPen(QPen(
|
painter.setPen(QPen(
|
||||||
@ -620,14 +660,14 @@ class Vision(Component):
|
|||||||
getattr(Qt, item.get("pen_join", "MiterJoin")),
|
getattr(Qt, item.get("pen_join", "MiterJoin")),
|
||||||
))
|
))
|
||||||
if item["shape"] == "ellipse":
|
if item["shape"] == "ellipse":
|
||||||
painter.drawEllipse(QPointF(v["xc"], v["yc"]), v["w"] / 2, v["h"] / 2)
|
painter.drawEllipse(QPointF(p["xc"], p["yc"]), p["w"] / 2, p["h"] / 2)
|
||||||
elif item["shape"] == "cross":
|
elif item["shape"] == "cross":
|
||||||
painter.drawLine(QLineF(v["xc"], v["y1"], v["xc"], v["y2"]))
|
painter.drawLine(QLineF(p["xc"], p["y1"], p["xc"], p["y2"]))
|
||||||
painter.drawLine(QLineF(v["x1"], v["yc"], v["x2"], v["yc"]))
|
painter.drawLine(QLineF(p["x1"], p["yc"], p["x2"], p["yc"]))
|
||||||
elif item["shape"] == "line":
|
elif item["shape"] == "line":
|
||||||
painter.drawLine(QLineF(v["xc"], v["yc"], v["x2"], v["y2"]))
|
painter.drawLine(QLineF(p["xc"], p["yc"], p["x2"], p["y2"]))
|
||||||
elif item["shape"] == "rect":
|
elif item["shape"] == "rect":
|
||||||
painter.drawRect(QRectF(v["x1"], v["y1"], v["x2"], v["y2"]))
|
painter.drawRect(QRectF(QPointF(p["x1"], p["y1"]), QPointF(p["x2"], p["y2"])))
|
||||||
elif item["shape"] == "text":
|
elif item["shape"] == "text":
|
||||||
old_render_hints = painter.renderHints()
|
old_render_hints = painter.renderHints()
|
||||||
painter.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing, True)
|
painter.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing, True)
|
||||||
@ -640,7 +680,7 @@ class Vision(Component):
|
|||||||
font.setWordSpacing(item.get("font_word_spacing", 0))
|
font.setWordSpacing(item.get("font_word_spacing", 0))
|
||||||
font.setPixelSize(round(item.get("font_size", 25)))
|
font.setPixelSize(round(item.get("font_size", 25)))
|
||||||
path = QPainterPath()
|
path = QPainterPath()
|
||||||
path.addText(v["x1"], v["y1"], font, item["text"])
|
path.addText(p["x1"], p["y1"], font, item["text"])
|
||||||
painter.drawPath(path)
|
painter.drawPath(path)
|
||||||
painter.setRenderHints(old_render_hints, True)
|
painter.setRenderHints(old_render_hints, True)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import glob
|
import glob
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@ -26,7 +27,11 @@ class VisionSaver(Component):
|
|||||||
self.minimum_disk_free_space_gb = float(self.minimum_disk_free_space_gb)
|
self.minimum_disk_free_space_gb = float(self.minimum_disk_free_space_gb)
|
||||||
self.time_format = self.config[self.name]["time_format"]
|
self.time_format = self.config[self.name]["time_format"]
|
||||||
|
|
||||||
def save(self, save_time, img, mask=True, resize=True):
|
def save(self, save_time=None, suffix=None, frame=None, vision=None, resize=None, mask=None):
|
||||||
|
self.remove_older_images_if_needed()
|
||||||
|
if type(save_time) is None:
|
||||||
|
save_time = datetime.now()
|
||||||
|
else:
|
||||||
if type(save_time) is float:
|
if type(save_time) is float:
|
||||||
save_time = int(save_time)
|
save_time = int(save_time)
|
||||||
if type(save_time) is int:
|
if type(save_time) is int:
|
||||||
@ -36,24 +41,46 @@ class VisionSaver(Component):
|
|||||||
timestamp = save_time.strftime(self.time_format)
|
timestamp = save_time.strftime(self.time_format)
|
||||||
save_dir = self.location / save_time.strftime("%Y") / save_time.strftime("%m")
|
save_dir = self.location / save_time.strftime("%Y") / save_time.strftime("%m")
|
||||||
os.makedirs(save_dir, exist_ok=True)
|
os.makedirs(save_dir, exist_ok=True)
|
||||||
out_path = save_dir / f"{timestamp}.png"
|
out_paths = []
|
||||||
self.log.info(f"saving {out_path}")
|
if frame is not None:
|
||||||
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
|
if suffix is not None:
|
||||||
if resize and self.resize_resolution is not None:
|
out_paths.append(save_dir / f"{timestamp}.{suffix}.png")
|
||||||
img = cv2.resize(img, self.resize_resolution, interpolation=cv2.INTER_LINEAR)
|
|
||||||
if mask and self.mask_zones is not None:
|
|
||||||
height, width, channels = img.shape
|
|
||||||
out = np.full(
|
|
||||||
[height, width, channels],
|
|
||||||
[0] * channels
|
|
||||||
)
|
|
||||||
for zone_name in self.mask_zones:
|
|
||||||
zone = self.bench.zones[zone_name]["box"]
|
|
||||||
out[zone[1]:zone[3], zone[0]:zone[2]] = img[zone[1]:zone[3], zone[0]:zone[2]]
|
|
||||||
else:
|
else:
|
||||||
out = img
|
out_paths.append(save_dir / f"{timestamp}.png")
|
||||||
cv2.imwrite(str(out_path), out)
|
self.log.info(f"saving {out_paths[-1]}")
|
||||||
return out_path
|
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
|
||||||
|
# resize
|
||||||
|
if resize is None or resize is True:
|
||||||
|
resize = self.resize_resolution
|
||||||
|
elif resize is False:
|
||||||
|
resize = None
|
||||||
|
if resize is not None:
|
||||||
|
frame = cv2.resize(frame, resize, interpolation=cv2.INTER_LINEAR)
|
||||||
|
# mask
|
||||||
|
if mask is None or mask is True:
|
||||||
|
mask = self.mask_zones
|
||||||
|
elif mask is False:
|
||||||
|
mask = None
|
||||||
|
if mask is not None:
|
||||||
|
height, width, channels = frame.shape
|
||||||
|
out = np.full([height, width, channels], [0] * channels)
|
||||||
|
for zone_name in mask:
|
||||||
|
zone = self.bench.zones[zone_name]["box"]
|
||||||
|
out[zone[1]:zone[3], zone[0]:zone[2]] = frame[zone[1]:zone[3], zone[0]:zone[2]]
|
||||||
|
else:
|
||||||
|
out = frame
|
||||||
|
# save frame
|
||||||
|
cv2.imwrite(str(out_paths[-1]), out)
|
||||||
|
if vision is not None:
|
||||||
|
if suffix is not None:
|
||||||
|
out_paths.append(save_dir / f"{timestamp}.{suffix}.json")
|
||||||
|
else:
|
||||||
|
out_paths.append(save_dir / f"{timestamp}.json")
|
||||||
|
self.log.info(f"saving {out_paths[-1]}")
|
||||||
|
# save vision
|
||||||
|
with open(out_paths[-1], "w") as f:
|
||||||
|
json.dump(vision, f)
|
||||||
|
return out_paths
|
||||||
|
|
||||||
def remove_older_images_if_needed(self):
|
def remove_older_images_if_needed(self):
|
||||||
if self.minimum_disk_free_space_gb is None:
|
if self.minimum_disk_free_space_gb is None:
|
||||||
|
|||||||
@ -46,19 +46,19 @@ class Archive(Widget):
|
|||||||
replace_widget(self, "crud_w", self.crud)
|
replace_widget(self, "crud_w", self.crud)
|
||||||
self.selected = None
|
self.selected = None
|
||||||
self.print_b.setEnabled(False)
|
self.print_b.setEnabled(False)
|
||||||
self.crud().db_tw.setSelectionBehavior(QAbstractItemView.SelectRows)
|
self.crud.db_tw.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
self.crud().db_tw.setSelectionMode(QAbstractItemView.SingleSelection)
|
self.crud.db_tw.setSelectionMode(QAbstractItemView.SingleSelection)
|
||||||
self.crud().db_tw.itemSelectionChanged.connect(self.check)
|
self.crud.db_tw.itemSelectionChanged.connect(self.check)
|
||||||
self.print_b.clicked.connect(self.print_label)
|
self.print_b.clicked.connect(self.print_label)
|
||||||
|
|
||||||
def check(self):
|
def check(self):
|
||||||
if not self.crud().modified:
|
if not self.crud.modified:
|
||||||
selected = self.crud().get_selected_rows()
|
selected = self.crud.get_selected_rows()
|
||||||
if len(selected) == 1:
|
if len(selected) == 1:
|
||||||
selected = selected[0] - 1 # - 1 because rn starts from 1 (filters line)
|
selected = selected[0] - 1 # - 1 because rn starts from 1 (filters line)
|
||||||
if selected >= 0 and selected < len(self.crud().data_index):
|
if selected >= 0 and selected < len(self.crud.data_index):
|
||||||
selected = self.crud().data_index[selected]
|
selected = self.crud.data_index[selected]
|
||||||
self.selected = self.crud().db.table_model.get_by_id(selected)
|
self.selected = self.crud.db.table_model.get_by_id(selected)
|
||||||
self.print_b.setEnabled(True)
|
self.print_b.setEnabled(True)
|
||||||
return
|
return
|
||||||
self.selected = None
|
self.selected = None
|
||||||
|
|||||||
@ -46,19 +46,19 @@ class Autotests_Archive(Widget):
|
|||||||
replace_widget(self, "crud_w", self.crud)
|
replace_widget(self, "crud_w", self.crud)
|
||||||
self.selected = None
|
self.selected = None
|
||||||
self.print_b.setEnabled(False)
|
self.print_b.setEnabled(False)
|
||||||
self.crud().db_tw.setSelectionBehavior(QAbstractItemView.SelectRows)
|
self.crud.db_tw.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
self.crud().db_tw.setSelectionMode(QAbstractItemView.SingleSelection)
|
self.crud.db_tw.setSelectionMode(QAbstractItemView.SingleSelection)
|
||||||
self.crud().db_tw.itemSelectionChanged.connect(self.check)
|
self.crud.db_tw.itemSelectionChanged.connect(self.check)
|
||||||
self.print_b.clicked.connect(self.print_label)
|
self.print_b.clicked.connect(self.print_label)
|
||||||
|
|
||||||
def check(self):
|
def check(self):
|
||||||
if not self.crud().modified:
|
if not self.crud.modified:
|
||||||
selected = self.crud().get_selected_rows()
|
selected = self.crud.get_selected_rows()
|
||||||
if len(selected) == 1:
|
if len(selected) == 1:
|
||||||
selected = selected[0] - 1 # - 1 because rn starts from 1 (filters line)
|
selected = selected[0] - 1 # - 1 because rn starts from 1 (filters line)
|
||||||
if selected >= 0 and selected < len(self.crud().data_index):
|
if selected >= 0 and selected < len(self.crud.data_index):
|
||||||
selected = self.crud().data_index[selected]
|
selected = self.crud.data_index[selected]
|
||||||
self.selected = self.crud().db.table_model.get_by_id(selected)
|
self.selected = self.crud.db.table_model.get_by_id(selected)
|
||||||
self.print_b.setEnabled(True)
|
self.print_b.setEnabled(True)
|
||||||
return
|
return
|
||||||
self.selected = None
|
self.selected = None
|
||||||
|
|||||||
@ -26,6 +26,18 @@
|
|||||||
<string>Crud</string>
|
<string>Crud</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QGroupBox" name="db_gb">
|
<widget class="QGroupBox" name="db_gb">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
|||||||
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>28</width>
|
<width>94</width>
|
||||||
<height>28</height>
|
<height>16</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -20,6 +20,18 @@
|
|||||||
<string>Dialog</string>
|
<string>Dialog</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QWidget" name="centralWidget" native="true">
|
<widget class="QWidget" name="centralWidget" native="true">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
|||||||
@ -1,4 +1,10 @@
|
|||||||
|
from PyQt5.QtGui import QColor
|
||||||
|
|
||||||
|
|
||||||
def calc_foreground_color(background_color):
|
def calc_foreground_color(background_color):
|
||||||
|
if type(background_color) is QColor:
|
||||||
|
background_color = [background_color.red(), background_color.green(), background_color.blue(), ]
|
||||||
|
to_qcolor = True
|
||||||
colors = []
|
colors = []
|
||||||
for c in background_color[:3]:
|
for c in background_color[:3]:
|
||||||
c /= 255 # 8bit to sRGB
|
c /= 255 # 8bit to sRGB
|
||||||
@ -8,6 +14,8 @@ def calc_foreground_color(background_color):
|
|||||||
c = ((c + 0.055) / 1.055) ** 2.4
|
c = ((c + 0.055) / 1.055) ** 2.4
|
||||||
colors.append(c)
|
colors.append(c)
|
||||||
# Luminance
|
# Luminance
|
||||||
L = 0.2126 * colors[0] + 0.7152 * colors[1] + 0.0722 * colors[1]
|
L = 0.2126 * colors[0] + 0.7152 * colors[1] + 0.0722 * colors[2]
|
||||||
foreground_color = [(1 - round(L)) * 255] * 3
|
foreground_color = [(1 - round(L)) * 255] * 3
|
||||||
|
if to_qcolor:
|
||||||
|
foreground_color = QColor(*foreground_color)
|
||||||
return foreground_color
|
return foreground_color
|
||||||
|
|||||||
@ -6,14 +6,26 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>987</width>
|
<width>955</width>
|
||||||
<height>210</height>
|
<height>161</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Leak Step Editor</string>
|
<string>Leak Step Editor</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
|
|||||||
@ -6,14 +6,26 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>800</width>
|
<width>347</width>
|
||||||
<height>600</height>
|
<height>50</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Recipe Selection</string>
|
<string>Recipe Selection</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QPushButton" name="select_b">
|
<widget class="QPushButton" name="select_b">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
|||||||
@ -38,18 +38,18 @@ class Test(Widget):
|
|||||||
self.step = None
|
self.step = None
|
||||||
# INIT CYCLE STATES
|
# INIT CYCLE STATES
|
||||||
self.cycle_available_steps = {
|
self.cycle_available_steps = {
|
||||||
# "assembly_1": Test_Assembly(self.select_step_img("assembly_1"), u"INSERIRE SENSORE"),
|
# "assembly_1": Test_Assembly(img_path=self.select_step_img("assembly_1"), text=u"INSERIRE SENSORE", widget=None),
|
||||||
"autotest": Test_Assembly(None, u"ESEGUIRE PROCEDURA DI AUTOTEST", Test_Autotest()),
|
"autotest": Test_Assembly(img_path=None, text=u"ESEGUIRE PROCEDURA DI AUTOTEST", widget=Test_Autotest()),
|
||||||
"barcodes": Test_Assembly(self.select_step_img("scan"), u"LEGGERE IL BARCODE DEL PEZZO DA COLLAUDARE", Test_Barcodes()),
|
"barcodes": Test_Assembly(img_path=self.select_step_img("scan"), text=u"LEGGERE IL BARCODE DEL PEZZO DA COLLAUDARE", widget=Test_Barcodes()),
|
||||||
"done": Test_Assembly(self.select_step_img("success"), u"COLLAUDO COMPLETATO"),
|
"done": Test_Assembly(img_path=self.select_step_img("success"), text=u"COLLAUDO COMPLETATO", widget=None),
|
||||||
"emergency": Test_Assembly(self.select_step_img("reset_emergency"), u"EMERGENZA INTERVENUTA - RIPRISTINARE PULSANTE E SELEZIONARE \"RESET EMERGENZA\" DAL MEN\u00d9 \"STRUMENTI\""),
|
"emergency": Test_Assembly(img_path=self.select_step_img("reset_emergency"), text=u"EMERGENZA INTERVENUTA - RIPRISTINARE PULSANTE E SELEZIONARE \"RESET EMERGENZA\" DAL MEN\u00d9 \"STRUMENTI\"", widget=None),
|
||||||
"fail": Test_Assembly(self.select_step_img("fail"), u"CICLO INTERROTTO"),
|
"fail": Test_Assembly(img_path=self.select_step_img("fail"), text=u"CICLO INTERROTTO", widget=None),
|
||||||
"leak": Test_Assembly(None, u"PREMERE START PER INIZIARE LA PROVA TENUTA", Test_Leak(components=self.components, recipe=self.recipe, step=self.step)),
|
"leak": Test_Assembly(img_path=None, text=None, widget=Test_Leak(components=self.components, recipe=self.recipe, step=self.step)),
|
||||||
"print": Test_Assembly(self.select_step_img("print"), u"STAMPA ETICHETTA IN CORSO"),
|
"print": Test_Assembly(img_path=self.select_step_img("print"), text=u"STAMPA ETICHETTA IN CORSO", widget=None),
|
||||||
"select_recipe": Test_Assembly(None, u"SELEZIONARE IL CODICE DA COLLAUDARE", Recipe_Selection()),
|
"select_recipe": Test_Assembly(img_path=None, text=u"SELEZIONARE IL CODICE DA COLLAUDARE", widget=Recipe_Selection()),
|
||||||
"vision": Test_Assembly(None, u"VERIFICARE CONTROLLO CON TELECAMERA", Test_Vision(components=self.components, recipe=self.recipe, step=self.step)),
|
"vision": Test_Assembly(img_path=None, text=u"VERIFICARE CONTROLLO CON TELECAMERA", widget=Test_Vision(components=self.components, recipe=self.recipe, step=self.step)),
|
||||||
"wait": Test_Assembly(self.select_step_img("wait"), u"ATTENDERE - PAUSA INTER CICLO"),
|
"wait": Test_Assembly(img_path=self.select_step_img("wait"), text=u"ATTENDERE - PAUSA INTER CICLO", widget=None),
|
||||||
None: Test_Assembly(self.select_step_img("warning"), u"ATTENZIONE - LA RICETTA SELEZIONATA NON CONTIENE FASI DI TEST"),
|
None: Test_Assembly(img_path=self.select_step_img("warning"), text=u"ATTENZIONE - LA RICETTA SELEZIONATA NON CONTIENE FASI DI TEST", widget=None),
|
||||||
}
|
}
|
||||||
self.cycle_steps = None
|
self.cycle_steps = None
|
||||||
self.cycle_index = -1
|
self.cycle_index = -1
|
||||||
@ -155,16 +155,19 @@ class Test(Widget):
|
|||||||
# RESET TEST DATA
|
# RESET TEST DATA
|
||||||
self.data = {"ok": True, "overridden": False}
|
self.data = {"ok": True, "overridden": False}
|
||||||
self.archived = None
|
self.archived = None
|
||||||
|
# COUNT RESET
|
||||||
|
self.pieces[0] = 0
|
||||||
|
self.pieces[1] = 0
|
||||||
elif action == "fail":
|
elif action == "fail":
|
||||||
self.log.info(f"cycle next: action: {action!r}")
|
self.log.info(f"cycle next: action: {action!r}")
|
||||||
# COUNT FAIL
|
|
||||||
self.pieces[1] += 1
|
|
||||||
# FAIL AND RESTART TEST
|
# FAIL AND RESTART TEST
|
||||||
self.step = Steps(type="fail")
|
self.step = Steps(type="fail")
|
||||||
self.cycle_index = -1
|
self.cycle_index = -1
|
||||||
# RESET TEST DATA
|
# RESET TEST DATA
|
||||||
self.data = {"ok": True, "overridden": False}
|
self.data = {"ok": True, "overridden": False}
|
||||||
self.archived = None
|
self.archived = None
|
||||||
|
# COUNT FAIL
|
||||||
|
self.pieces[1] += 1
|
||||||
elif action is not None:
|
elif action is not None:
|
||||||
raise NotImplementedError(f"cycle next: action {action!r} is not a valid action")
|
raise NotImplementedError(f"cycle next: action {action!r} is not a valid action")
|
||||||
# if action did not set the next cycle step
|
# if action did not set the next cycle step
|
||||||
@ -270,11 +273,13 @@ class Test(Widget):
|
|||||||
|
|
||||||
def done(self, ok=True):
|
def done(self, ok=True):
|
||||||
self.log.info("cycle done")
|
self.log.info("cycle done")
|
||||||
t = self.data.get("vision", {}).get(0, {}).get("time", None)
|
vision_test_1 = self.data.get("vision", {}).get(0, {})
|
||||||
f = self.data.get("vision", {}).get(0, {}).get("frame", None)
|
out_paths = self.components["vision_saver"].save(
|
||||||
if t is not None and f is not None:
|
save_time=vision_test_1.get("time", None),
|
||||||
file_path = self.components["vision_saver"].save(t, f)
|
frame=vision_test_1.get("frame", None),
|
||||||
self.log.info(f"cycle vision image saved locally: {file_path!r}")
|
# vision=vision_test_1.get("detections", None),
|
||||||
|
)
|
||||||
|
self.log.info(f"cycle vision saved locally: {out_paths!r}")
|
||||||
for vision in self.data["vision"].values():
|
for vision in self.data["vision"].values():
|
||||||
vision.pop("frame", None)
|
vision.pop("frame", None)
|
||||||
vision.pop("render", None)
|
vision.pop("render", None)
|
||||||
@ -287,10 +292,14 @@ class Test(Widget):
|
|||||||
def print(self, archived=None):
|
def print(self, archived=None):
|
||||||
self.log.info("cycle print")
|
self.log.info("cycle print")
|
||||||
# LABEL PRINT
|
# LABEL PRINT
|
||||||
|
leak_test_1 = self.data.get("leak", {}).get(0, {})
|
||||||
|
leak_test_1_step_spec = leak_test_1.get("step", {}).get("spec", {})
|
||||||
|
leak_test_1_results = leak_test_1.get("results", {})
|
||||||
|
leak_test_1_results_data = leak_test_1_results.get("data", {})
|
||||||
datamatrix = str(archived.recipe.part_number) + archived.time.strftime("%m%y") + f"{archived.id:0>5}"
|
datamatrix = str(archived.recipe.part_number) + archived.time.strftime("%m%y") + f"{archived.id:0>5}"
|
||||||
pmax = self.data.get("leak", {}).get(0, {}).get("step", {}).get("spec", {}).get("test_pressure", "-")
|
pmax = leak_test_1_step_spec.get("test_pressure", "-")
|
||||||
pmin = self.data.get("leak", {}).get(0, {}).get("results", {}).get("data", {}).get("Running test: pressure at the end of settling", "-")
|
pmin = leak_test_1_results_data.get("Running test: pressure at the end of settling", "-")
|
||||||
leak = self.data.get("leak", {}).get(0, {}).get("results", {}).get("data", {}).get("Running test: measured leak", "-")
|
leak = leak_test_1_results_data.get("Running test: measured leak", "-")
|
||||||
context = {
|
context = {
|
||||||
"DATAMATRIX": datamatrix,
|
"DATAMATRIX": datamatrix,
|
||||||
"DATAMATRIX_TEXT": datamatrix,
|
"DATAMATRIX_TEXT": datamatrix,
|
||||||
@ -302,13 +311,13 @@ class Test(Widget):
|
|||||||
"PMAX": f"{pmax:.3f}" if type(pmax) is not str else pmax,
|
"PMAX": f"{pmax:.3f}" if type(pmax) is not str else pmax,
|
||||||
"PMIN": f"{pmin:.3f}" if type(pmin) is not str else pmin,
|
"PMIN": f"{pmin:.3f}" if type(pmin) is not str else pmin,
|
||||||
"LEAK": f"{leak:.3f}" if type(leak) is not str else leak,
|
"LEAK": f"{leak:.3f}" if type(leak) is not str else leak,
|
||||||
"TFILL": str(self.data.get("leak", {}).get(0, {}).get("step", {}).get("spec", {}).get("filling_time", "-")),
|
"TFILL": str(leak_test_1_step_spec.get("filling_time", "-")),
|
||||||
"TSTAB": str(self.data.get("leak", {}).get(0, {}).get("step", {}).get("spec", {}).get("settling_time", "-")),
|
"TSTAB": str(leak_test_1_step_spec.get("settling_time", "-")),
|
||||||
"TTEST": str(self.data.get("leak", {}).get(0, {}).get("step", {}).get("spec", {}).get("test_time", "-")),
|
"TTEST": str(leak_test_1_step_spec.get("test_time", "-")),
|
||||||
"MAXLEAK": str(self.data.get("leak", {}).get(0, {}).get("step", {}).get("spec", {}).get("test_pressure_max_delta", "-")),
|
"MAXLEAK": str(leak_test_1_step_spec.get("test_pressure_max_delta", "-")),
|
||||||
"PTESTMIN": str(self.data.get("leak", {}).get(0, {}).get("step", {}).get("spec", {}).get("test_pressure_min_delta", "-")),
|
"PTESTMIN": str(leak_test_1_step_spec.get("test_pressure_min_delta", "-")),
|
||||||
"RESULT_L1": "ESITO" + str(" FORZATO" if self.data.get("overridden", False) else ""),
|
"RESULT_L1": "ESITO" + str(" FORZATO" if self.data.get("overridden", False) else ""),
|
||||||
"RESULT_L2": str("CONFORME" if self.data.get("leak", {}).get(0, {}).get("results", {}).get("ok", False) else "SCARTO"),
|
"RESULT_L2": str("CONFORME" if leak_test_1_results.get("ok", False) else "SCARTO"),
|
||||||
}
|
}
|
||||||
self.components["label_printer"].print_label("EtichettaR5", context=context)
|
self.components["label_printer"].print_label("EtichettaR5", context=context)
|
||||||
self.log.info(f"cycle printed: {context!r}")
|
self.log.info(f"cycle printed: {context!r}")
|
||||||
|
|||||||
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1003</width>
|
<width>804</width>
|
||||||
<height>255</height>
|
<height>86</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
|||||||
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>422</width>
|
<width>184</width>
|
||||||
<height>139</height>
|
<height>103</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import weakref
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt
|
||||||
from PyQt5.QtGui import QPixmap
|
from PyQt5.QtGui import QPixmap
|
||||||
from ui.helpers import replace_widget
|
from ui.helpers import replace_widget
|
||||||
@ -39,6 +41,8 @@ class Test_Assembly(Widget):
|
|||||||
else:
|
else:
|
||||||
if hasattr(self, attr):
|
if hasattr(self, attr):
|
||||||
delattr(self, attr)
|
delattr(self, attr)
|
||||||
|
if hasattr(widget, "set_parent_assembly_widget"):
|
||||||
|
widget.set_parent_assembly_widget(weakref.ref(self))
|
||||||
self.widget.setVisible(True)
|
self.widget.setVisible(True)
|
||||||
else:
|
else:
|
||||||
self.widget.setVisible(False)
|
self.widget.setVisible(False)
|
||||||
|
|||||||
@ -7,13 +7,25 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>94</width>
|
<width>94</width>
|
||||||
<height>108</height>
|
<height>89</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Test Assembly</string>
|
<string>Test Assembly</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="img_l">
|
<widget class="QLabel" name="img_l">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
|||||||
@ -6,14 +6,27 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>18</width>
|
<width>94</width>
|
||||||
<height>18</height>
|
<height>16</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Test Autotest</string>
|
<string>Test Autotest</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout"/>
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|||||||
@ -6,14 +6,26 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>187</width>
|
<width>169</width>
|
||||||
<height>162</height>
|
<height>144</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Test Barcodes</string>
|
<string>Test Barcodes</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
<item row="13" column="0">
|
<item row="13" column="0">
|
||||||
<widget class="QLineEdit" name="barcodes_le"/>
|
<widget class="QLineEdit" name="barcodes_le"/>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@ -15,6 +15,10 @@ class Test_Leak(Test_Test):
|
|||||||
self.components["tecna_t3"].write_recipe(self.recipe, self.step)
|
self.components["tecna_t3"].write_recipe(self.recipe, self.step)
|
||||||
self.get_connection = self.components["tecna_t3"].out.connect(self.get)
|
self.get_connection = self.components["tecna_t3"].out.connect(self.get)
|
||||||
self.components["tecna_t3"].resume()
|
self.components["tecna_t3"].resume()
|
||||||
|
if self.parent_assembly_widget is not None:
|
||||||
|
self.parent_assembly_widget().set_text(text=None)
|
||||||
|
self.start_b.setEnabled(False)
|
||||||
|
self.stop_b.setEnabled(False)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
# disable tes loop
|
# disable tes loop
|
||||||
@ -22,6 +26,10 @@ class Test_Leak(Test_Test):
|
|||||||
self.components["tecna_t3"].pause()
|
self.components["tecna_t3"].pause()
|
||||||
self.disconnect(self.get_connection)
|
self.disconnect(self.get_connection)
|
||||||
super().stop()
|
super().stop()
|
||||||
|
if self.parent_assembly_widget is not None:
|
||||||
|
self.parent_assembly_widget().set_text(text=None)
|
||||||
|
self.start_b.setEnabled(False)
|
||||||
|
self.stop_b.setEnabled(False)
|
||||||
|
|
||||||
def get(self, data=None, override=False):
|
def get(self, data=None, override=False):
|
||||||
if self.done: # avoid proccessing if completed
|
if self.done: # avoid proccessing if completed
|
||||||
@ -62,6 +70,21 @@ class Test_Leak(Test_Test):
|
|||||||
if type(v) is float:
|
if type(v) is float:
|
||||||
v = round(v, 2)
|
v = round(v, 2)
|
||||||
l.setText(str(v))
|
l.setText(str(v))
|
||||||
|
if d.get("Running test: active phase", None) in {
|
||||||
|
"WAITING START",
|
||||||
|
"ATTESA START",
|
||||||
|
"WAITING THE START OF A NEW TEST"
|
||||||
|
"FINE TEST",
|
||||||
|
}:
|
||||||
|
if self.parent_assembly_widget is not None:
|
||||||
|
self.parent_assembly_widget().set_text(text=u"PREMERE START PER INIZIARE LA PROVA TENUTA")
|
||||||
|
self.start_b.setEnabled(True)
|
||||||
|
self.stop_b.setEnabled(False)
|
||||||
|
else:
|
||||||
|
if self.parent_assembly_widget is not None:
|
||||||
|
self.parent_assembly_widget().set_text(text=u"PROVA TENUTA IN CORSO")
|
||||||
|
self.start_b.setEnabled(False)
|
||||||
|
self.stop_b.setEnabled(True)
|
||||||
super().visualize(data)
|
super().visualize(data)
|
||||||
|
|
||||||
def save_last(self):
|
def save_last(self):
|
||||||
|
|||||||
@ -6,14 +6,26 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>980</width>
|
<width>370</width>
|
||||||
<height>704</height>
|
<height>491</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Test Leak</string>
|
<string>Test Leak</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
<item row="0" column="0" colspan="2">
|
<item row="0" column="0" colspan="2">
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import sys
|
import sys
|
||||||
|
import weakref
|
||||||
|
|
||||||
from lib.helpers import timing
|
from lib.helpers import timing
|
||||||
from PyQt5.QtCore import Qt, QTimer, pyqtSignal
|
from PyQt5.QtCore import Qt, QTimer, pyqtSignal
|
||||||
@ -40,6 +41,7 @@ class Test_Test(Widget):
|
|||||||
self.override_b.clicked.connect(self.override)
|
self.override_b.clicked.connect(self.override)
|
||||||
self.override_b.setEnabled(True)
|
self.override_b.setEnabled(True)
|
||||||
# setup vision staus gui
|
# setup vision staus gui
|
||||||
|
self.parent_assembly_widget = None
|
||||||
self.status_imgs_full = {
|
self.status_imgs_full = {
|
||||||
True: QPixmap("src/ui/imgs/success.png"),
|
True: QPixmap("src/ui/imgs/success.png"),
|
||||||
"": QPixmap("src/ui/imgs/neo.ico"),
|
"": QPixmap("src/ui/imgs/neo.ico"),
|
||||||
@ -61,6 +63,14 @@ class Test_Test(Widget):
|
|||||||
self.status_palettes[""].setColor(QPalette.Base, QColor(255, 255, 0))
|
self.status_palettes[""].setColor(QPalette.Base, QColor(255, 255, 0))
|
||||||
self.visualize()
|
self.visualize()
|
||||||
|
|
||||||
|
def set_parent_assembly_widget(self, parent_assembly_widget=None):
|
||||||
|
if parent_assembly_widget is None:
|
||||||
|
self.parent_assembly_widget = None
|
||||||
|
elif type(parent_assembly_widget) is weakref.ReferenceType:
|
||||||
|
self.parent_assembly_widget = parent_assembly_widget
|
||||||
|
else:
|
||||||
|
self.parent_assembly_widget = weakref.ref(parent_assembly_widget)
|
||||||
|
|
||||||
def start(self, recipe=None, step=None):
|
def start(self, recipe=None, step=None):
|
||||||
self.admin_challenged = False
|
self.admin_challenged = False
|
||||||
self.recipe = recipe
|
self.recipe = recipe
|
||||||
|
|||||||
@ -32,7 +32,7 @@
|
|||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Risultato</string>
|
<string>Risultato</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QProgressBar" name="ok_counter_pb">
|
<widget class="QProgressBar" name="ok_counter_pb">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -99,7 +99,7 @@
|
|||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>SALVA IMMAGINE</string>
|
<string>SALVA</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal
|
from PyQt5.QtCore import pyqtSignal
|
||||||
from PyQt5.QtGui import QImage, QPixmap
|
from PyQt5.QtGui import QColor, QImage, QPalette, QPixmap
|
||||||
|
from PyQt5.QtWidgets import QHeaderView, QProgressBar, QTableWidgetItem
|
||||||
|
from ui.helpers import calc_foreground_color
|
||||||
from ui.test_test import Test_Test
|
from ui.test_test import Test_Test
|
||||||
|
|
||||||
|
|
||||||
@ -13,7 +15,17 @@ class Test_Vision(Test_Test):
|
|||||||
self.ok_counter_limit = 2
|
self.ok_counter_limit = 2
|
||||||
else:
|
else:
|
||||||
self.ok_counter_limit = 1
|
self.ok_counter_limit = 1
|
||||||
|
# DETECTIONS TABLE
|
||||||
|
self.results_table_headers = {
|
||||||
|
"class": "RILEVATO",
|
||||||
|
"expected": "ATTESO",
|
||||||
|
"score": "PUNTEGGIO",
|
||||||
|
}
|
||||||
super().__init__(components=components, recipe=recipe, step=step)
|
super().__init__(components=components, recipe=recipe, step=step)
|
||||||
|
self.results_tw.setColumnCount(len(self.results_table_headers))
|
||||||
|
self.results_tw.setHorizontalHeaderLabels(self.results_table_headers.values())
|
||||||
|
self.results_tw.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||||
|
self.results_tw.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||||
|
|
||||||
def start(self, recipe=None, step=None):
|
def start(self, recipe=None, step=None):
|
||||||
super().start(recipe=recipe, step=step)
|
super().start(recipe=recipe, step=step)
|
||||||
@ -27,6 +39,9 @@ class Test_Vision(Test_Test):
|
|||||||
self.components["vision"].resume()
|
self.components["vision"].resume()
|
||||||
self.components["galaxy_camera"].resume()
|
self.components["galaxy_camera"].resume()
|
||||||
self.request_frame.emit() # request first frame
|
self.request_frame.emit() # request first frame
|
||||||
|
# DETECTIONS TABLE
|
||||||
|
# hide previous results
|
||||||
|
self.results_tw.setRowCount(0)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
# disable camera-vision loop
|
# disable camera-vision loop
|
||||||
@ -52,12 +67,36 @@ class Test_Vision(Test_Test):
|
|||||||
"render": data["vision"].get("render", None),
|
"render": data["vision"].get("render", None),
|
||||||
}], override=override)
|
}], override=override)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def tr(text):
|
||||||
|
translations = {
|
||||||
|
"no_detection": "non_rilevato",
|
||||||
|
"_": " ",
|
||||||
|
"big": "grande",
|
||||||
|
"black": "nero",
|
||||||
|
"blue": "blu",
|
||||||
|
"brown": "marrone",
|
||||||
|
"empty": "vuoto",
|
||||||
|
"green": "verde",
|
||||||
|
"ko": "ko",
|
||||||
|
"ok": "ok",
|
||||||
|
"orange": "arancione",
|
||||||
|
"red": "rosso",
|
||||||
|
"small": "piccolo",
|
||||||
|
"white": "bianco",
|
||||||
|
"yellow": "giallo",
|
||||||
|
}
|
||||||
|
for s, t in translations.items():
|
||||||
|
text = text.replace(s, t)
|
||||||
|
return text
|
||||||
|
|
||||||
def visualize(self, data=None):
|
def visualize(self, data=None):
|
||||||
if data is None:
|
if data is None:
|
||||||
data = {}
|
data = {}
|
||||||
overridden = data.get("overridden", False)
|
overridden = data.get("overridden", False)
|
||||||
frame = data.get("frame", None)
|
frame = data.get("frame", None)
|
||||||
render = data.get("render", None)
|
render = data.get("render", None)
|
||||||
|
results = data.get("results", {}).get("results", None)
|
||||||
if overridden:
|
if overridden:
|
||||||
img = self.status_imgs_full["warning"]
|
img = self.status_imgs_full["warning"]
|
||||||
elif render is not None:
|
elif render is not None:
|
||||||
@ -81,12 +120,84 @@ class Test_Vision(Test_Test):
|
|||||||
self.components["neo_pixels"].set_all_pixel_color("#ff0000")
|
self.components["neo_pixels"].set_all_pixel_color("#ff0000")
|
||||||
else:
|
else:
|
||||||
self.components["neo_pixels"].set_all_pixel_color("#ffffff")
|
self.components["neo_pixels"].set_all_pixel_color("#ffffff")
|
||||||
|
# DETECTIONS TABLE
|
||||||
|
if results is not None:
|
||||||
|
self.results_tw.setRowCount(len(results))
|
||||||
|
self.results_tw.setVerticalHeaderLabels(list(results))
|
||||||
|
for r, [zone_name, result] in enumerate(results.items()):
|
||||||
|
for c, header in enumerate(self.results_table_headers):
|
||||||
|
if header == "class":
|
||||||
|
i = self.results_tw.item(r, c)
|
||||||
|
if i is None:
|
||||||
|
i = QTableWidgetItem()
|
||||||
|
self.results_tw.setItem(r, c, i)
|
||||||
|
detection = result.get("detection", None)
|
||||||
|
if detection is not None:
|
||||||
|
text = self.tr(detection["class"]["name"])
|
||||||
|
color = QColor(detection["class"]["color"])
|
||||||
|
else:
|
||||||
|
text = ""
|
||||||
|
color = QColor("#ffffff")
|
||||||
|
i.setText(text)
|
||||||
|
i.setBackground(color)
|
||||||
|
i.setForeground(calc_foreground_color(color))
|
||||||
|
elif header == "expected":
|
||||||
|
i = self.results_tw.item(r, c)
|
||||||
|
if i is None:
|
||||||
|
i = QTableWidgetItem()
|
||||||
|
self.results_tw.setItem(r, c, i)
|
||||||
|
expected = result.get("expected", None)
|
||||||
|
if expected is not None:
|
||||||
|
text = self.tr(expected["name"])
|
||||||
|
color = QColor(expected["color"])
|
||||||
|
else:
|
||||||
|
text = ""
|
||||||
|
color = QColor("#ffffff")
|
||||||
|
i.setText(text)
|
||||||
|
i.setBackground(color)
|
||||||
|
i.setForeground(calc_foreground_color(color))
|
||||||
|
elif header == "score":
|
||||||
|
w = self.results_tw.cellWidget(r, c)
|
||||||
|
if w is None:
|
||||||
|
w = QProgressBar()
|
||||||
|
w.setRange(0, 100)
|
||||||
|
self.results_tw.setCellWidget(r, c, w)
|
||||||
|
score = result.get("detection", {}).get("score", None)
|
||||||
|
ok = result.get("ok", None)
|
||||||
|
if score is not None:
|
||||||
|
value = int(score * 100)
|
||||||
|
else:
|
||||||
|
value = 0
|
||||||
|
w.setValue(value)
|
||||||
|
if ok is not None:
|
||||||
|
if ok:
|
||||||
|
if score is not None:
|
||||||
|
color = QColor(int(255 - max(score - 0.5, 0) / 0.5 * 255), 255, 0)
|
||||||
|
else:
|
||||||
|
color = QColor("#00ff00")
|
||||||
|
else:
|
||||||
|
color = QColor("#ff0000")
|
||||||
|
else:
|
||||||
|
color = QColor("#0000ff")
|
||||||
|
p = QPalette()
|
||||||
|
p.setColor(QPalette.Highlight, color)
|
||||||
|
w.setPalette(p)
|
||||||
|
else:
|
||||||
|
raise NotImplementedError()
|
||||||
|
else:
|
||||||
|
self.results_tw.setRowCount(0)
|
||||||
super().visualize(data, img=img)
|
super().visualize(data, img=img)
|
||||||
|
|
||||||
def save_last(self):
|
def save_last(self):
|
||||||
if self.last is None:
|
if self.last is None:
|
||||||
return
|
return
|
||||||
self.components["vision_saver"].save(self.last["time"], self.last["frame"])
|
self.components["vision_saver"].save(
|
||||||
|
save_time=self.last.get("time", None),
|
||||||
|
frame=self.last.get("frame", None),
|
||||||
|
vision=self.last.get("detections", None),
|
||||||
|
suffix="manual_save",
|
||||||
|
resize=[256, 256],
|
||||||
|
)
|
||||||
|
|
||||||
def emit_ok(self):
|
def emit_ok(self):
|
||||||
super().emit_ok()
|
super().emit_ok()
|
||||||
|
|||||||
@ -6,15 +6,27 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>618</width>
|
<width>880</width>
|
||||||
<height>835</height>
|
<height>629</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Test Vision</string>
|
<string>Test Vision</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="2" column="0">
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="3" column="0">
|
||||||
<widget class="QPushButton" name="override_b">
|
<widget class="QPushButton" name="override_b">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
@ -27,13 +39,32 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0" colspan="2">
|
<item row="3" column="1">
|
||||||
|
<widget class="QPushButton" name="save_b">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>SALVA IMMAGINE</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="2">
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Risultato</string>
|
<string>Risultato</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="0" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QProgressBar" name="ok_counter_pb">
|
<widget class="QProgressBar" name="ok_counter_pb">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
@ -49,7 +80,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QLabel" name="state_l">
|
<widget class="QLabel" name="state_l">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||||
@ -72,6 +103,58 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0" colspan="2">
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="QWidget" name="widget" native="true">
|
||||||
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Visione</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QTableWidget" name="results_tw">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
<widget class="QLabel" name="img_l">
|
<widget class="QLabel" name="img_l">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
@ -81,8 +164,8 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>600</width>
|
<width>612</width>
|
||||||
<height>700</height>
|
<height>512</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -90,17 +173,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
</layout>
|
||||||
<widget class="QPushButton" name="save_b">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>SALVA IMMAGINE</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
@ -6,14 +6,26 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>174</width>
|
<width>143</width>
|
||||||
<height>91</height>
|
<height>67</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Vision Step Edito</string>
|
<string>Vision Step Edito</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
<item row="1" column="0" colspan="2">
|
<item row="1" column="0" colspan="2">
|
||||||
<widget class="QGroupBox" name="groupBox_6">
|
<widget class="QGroupBox" name="groupBox_6">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
|
|||||||
@ -13,7 +13,6 @@
|
|||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Window</string>
|
<string>Window</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget"/>
|
|
||||||
<widget class="QMenuBar" name="menubar">
|
<widget class="QMenuBar" name="menubar">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user