pynode-flow 0.2.0__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/.gitignore +1 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/INSTALL.md +2 -2
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/PKG-INFO +2 -4
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/README.md +1 -1
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/docs/DOCKER.md +0 -1
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/_version.py +3 -3
- pynode_flow-0.2.1/pynode/nodes/InferenceNode/InferenceEngine/__init__.py +5 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/InferenceNode/InferenceEngine/engines/ultralytics_engine.py +2 -2
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/InferenceNode/InferenceEngine/inference_engine_factory.py +1 -9
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/InferenceNode/InferenceEngine/readme.md +1 -1
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/InferenceNode/InferenceEngine/result_converters.py +15 -52
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/InferenceNode/inference_node.py +4 -5
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/InferenceNode/requirements.txt +0 -1
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode_flow.egg-info/PKG-INFO +2 -4
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode_flow.egg-info/SOURCES.txt +0 -4
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode_flow.egg-info/requires.txt +0 -2
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode_flow.egg-info/scm_file_list.json +210 -214
- pynode_flow-0.2.1/pynode_flow.egg-info/scm_version.json +8 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pyproject.toml +2 -4
- pynode_flow-0.2.0/pynode/nodes/GetiUploadNode/__init__.py +0 -3
- pynode_flow-0.2.0/pynode/nodes/GetiUploadNode/geti_upload_node.py +0 -278
- pynode_flow-0.2.0/pynode/nodes/GetiUploadNode/requirements.txt +0 -1
- pynode_flow-0.2.0/pynode/nodes/InferenceNode/InferenceEngine/__init__.py +0 -15
- pynode_flow-0.2.0/pynode/nodes/InferenceNode/InferenceEngine/engines/geti_engine.py +0 -309
- pynode_flow-0.2.0/pynode_flow.egg-info/scm_version.json +0 -8
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/.dockerignore +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/.github/workflows/ci.yml +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/.github/workflows/publish.yaml +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/DOCKER.md +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/Dockerfile +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/Dockerfile.cpu +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/LICENSE +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/MANIFEST.in +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/docker-compose.yml +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/docs/CREATING_NODES.md +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/docs/CUSTOM_NODES.md +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/docs/EXTENSIBILITY.md +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/docs/UI_COMPONENTS.md +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/examples/README.md +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/examples/camera_workflow.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/examples/camera_yolo_workflow.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/install_nodes.bat +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/install_nodes.sh +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/plan-pynodeRepoReview.prompt.md +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/__main__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/_perf.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/api/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/api/helpers.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/api/nodes.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/api/services.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/api/sse.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/api/uploads.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/api/workflows.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/config.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/install_nodes.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/main.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/node_registry.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/AutoSyncNode/auto_sync_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/BBoxMetricsNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/BBoxMetricsNode/bbox_metrics_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/BBoxMetricsNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/BatchNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/BatchNode/batch_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/BatchNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/CameraNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/CameraNode/camera_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/CameraNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ChangeNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ChangeNode/change_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ChangeNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ConfidenceFilterNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ConfidenceFilterNode/confidence_filter_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ConfidenceFilterNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/CounterNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/CounterNode/counter_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/CropNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/CropNode/crop_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/CropNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/DebugNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/DebugNode/debug_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/DebugNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/DelayNode/delay_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/DelayNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/DrawPredictionsNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/DrawPredictionsNode/draw_predictions_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/DrawPredictionsNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ErrorNode/error_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ErrorNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/FilterNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/FilterNode/filter_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/FilterNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/FrameSourceNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/FrameSourceNode/frame_source_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/FrameSourceNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/FunctionNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/FunctionNode/function_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/FunctionNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/GateNode/gate_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/GateNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ImageFormatNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ImageFormatNode/image_format_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ImageFormatNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ImageUploadNode/image_upload_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ImageViewerNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ImageViewerNode/image_viewer_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ImageViewerNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ImageWriterNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ImageWriterNode/imagewriter_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/ImageWriterNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/InferenceNode/InferenceEngine/device_detection.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/InferenceNode/InferenceEngine/engines/base_engine.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/InferenceNode/InferenceEngine/engines/example_engine_template.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/InferenceNode/InferenceEngine/engines/onnx_engine.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/InferenceNode/InferenceEngine/engines/pass_engine.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/InjectNode/inject_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/InjectNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/JoinNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/JoinNode/join_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/JoinNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/LabelFilterNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/LabelFilterNode/label_filter_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/LabelFilterNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/MQTTNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/MQTTNode/mqtt_in_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/MQTTNode/mqtt_out_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/MQTTNode/mqtt_service.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/MQTTNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/MessageWriterNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/MessageWriterNode/messagereader_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/MessageWriterNode/messagewriter_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OmronCameraNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OmronCameraNode/omron_camera_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OmronCameraNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/arithmetic_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/bitwise_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/blend_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/blob_detector_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/blur_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/color_space_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/colormap_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/contours_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/denormalize_coords_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/draw_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/edge_detector_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/equirectangular_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/fft_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/focus_estimation_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/frequency_filter_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/histogram_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/hough_circles_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/hough_lines_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/in_range_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/morphology_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/normalize_coords_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/paste_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/perspective_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/realsense_depth_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/resize_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/rotate_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/template_match_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/OpenCV/threshold_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/PointInShapeNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/PointInShapeNode/point_in_shape_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/PointInShapeNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/PolygonMetricsNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/PolygonMetricsNode/polygon_metrics_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/PolygonMetricsNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/QueueLengthProbeNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/QueueLengthProbeNode/queue_length_probe_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/Qwen3VLMNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/Qwen3VLMNode/qwen3_vlm_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/Qwen3VLMNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/RESTEndpointNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/RESTEndpointNode/rest_endpoint_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/RangeNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/RangeNode/range_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/RangeNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/RateProbeNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/RateProbeNode/rate_probe_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/RateProbeNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/RoboflowUploadNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/RoboflowUploadNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/RoboflowUploadNode/roboflow_upload_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/SliceNode/README.md +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/SliceNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/SliceNode/merge_predictions_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/SliceNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/SliceNode/slice_collector_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/SliceNode/slice_image_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/SplitNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/SplitNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/SplitNode/split_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/SwitchNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/SwitchNode/switch_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/SyncNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/SyncNode/sync_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/TemplateNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/TemplateNode/template_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/TrackerNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/TrackerNode/supervision_tracker_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/TrackerNode/tracker_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/UltralyticsNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/UltralyticsNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/UltralyticsNode/ultralytics_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/UnknownNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/VLLMNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/VLLMNode/vllm_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/VideoReaderNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/VideoReaderNode/video_reader_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/VideoWriterNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/VideoWriterNode/video_writer_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/WebhookNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/WebhookNode/webhook_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/base_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/image_utils.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/info.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/mDNSNode/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/mDNSNode/mdns_broadcast_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/mDNSNode/mdns_discovery_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/mDNSNode/mdns_manager.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/mDNSNode/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/messages.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/server.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/images/favicon4.png +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/index.html +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/README.md +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/auth.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/clipboard.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/config.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/connections.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/debug.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/events.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/history.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/main.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/minimap.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/nodes.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/palette.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/properties.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/selection.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/state.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/ui-utils.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/viewport.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/workflow.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/js/workflows.js +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/static/style.css +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/workflow_engine.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/workflow_manager.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode_flow.egg-info/dependency_links.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode_flow.egg-info/entry_points.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode_flow.egg-info/top_level.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/requirements.txt +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/setup.bat +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/setup.cfg +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/setup.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/setup.sh +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/__init__.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/conftest.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_api_auth.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_api_errors.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_api_nodes.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_api_security.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_api_workflows.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_base_node_messaging.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_concurrency.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_config.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_counter_sse.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_device_detection.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_message_reader_pickle.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_node_registration.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_node_types_api.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_persistence.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_serialization.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_video_reader_node.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_workflow_engine.py +0 -0
- {pynode_flow-0.2.0 → pynode_flow-0.2.1}/tests/test_workflow_roundtrip.py +0 -0
|
@@ -25,9 +25,9 @@ Install only the node groups you need:
|
|
|
25
25
|
| `vision` | ultralytics, torch, torchvision, supervision | UltralyticsNode, TrackerNode, DrawPredictionsNode, … |
|
|
26
26
|
| `mqtt` | paho-mqtt | MQTTNode |
|
|
27
27
|
| `camera` | framesource[full] | FrameSourceNode |
|
|
28
|
-
| `inference` | onnxruntime
|
|
28
|
+
| `inference` | onnxruntime (+ `vision`) | InferenceNode |
|
|
29
29
|
| `vlm` | transformers, qwen-vl-utils, Pillow (+ `vision`) | Qwen3VLMNode |
|
|
30
|
-
| `upload` | roboflow
|
|
30
|
+
| `upload` | roboflow | RoboflowUploadNode |
|
|
31
31
|
| `discovery` | zeroconf | mDNSNode |
|
|
32
32
|
| `full` | all of the above | every PyPI-installable node |
|
|
33
33
|
| `dev` | pytest, type stubs | (development only) |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pynode-flow
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Python based Node-RED-like visual workflow system
|
|
5
5
|
Author: olkham
|
|
6
6
|
License-Expression: MIT
|
|
@@ -38,7 +38,6 @@ Requires-Dist: framesource[full]; extra == "camera"
|
|
|
38
38
|
Provides-Extra: inference
|
|
39
39
|
Requires-Dist: pynode-flow[vision]; extra == "inference"
|
|
40
40
|
Requires-Dist: onnxruntime; extra == "inference"
|
|
41
|
-
Requires-Dist: geti-sdk>=2.0.0; extra == "inference"
|
|
42
41
|
Provides-Extra: vlm
|
|
43
42
|
Requires-Dist: pynode-flow[vision]; extra == "vlm"
|
|
44
43
|
Requires-Dist: transformers>=4.50.0; extra == "vlm"
|
|
@@ -46,7 +45,6 @@ Requires-Dist: qwen-vl-utils>=0.0.8; extra == "vlm"
|
|
|
46
45
|
Requires-Dist: Pillow>=9.0.0; extra == "vlm"
|
|
47
46
|
Provides-Extra: upload
|
|
48
47
|
Requires-Dist: roboflow>=1.0.0; extra == "upload"
|
|
49
|
-
Requires-Dist: geti-sdk>=2.0.0; extra == "upload"
|
|
50
48
|
Provides-Extra: discovery
|
|
51
49
|
Requires-Dist: zeroconf>=0.38.0; extra == "discovery"
|
|
52
50
|
Provides-Extra: full
|
|
@@ -499,7 +497,7 @@ Nodes can:
|
|
|
499
497
|
|
|
500
498
|
### Example Flow Documentation Needed
|
|
501
499
|
- ⬜ Bird seed level monitor
|
|
502
|
-
- ⬜ Capture data and send to Roboflow
|
|
500
|
+
- ⬜ Capture data and send to Roboflow
|
|
503
501
|
- ⬜ Track objects time in zone
|
|
504
502
|
- ⬜ Live VLMs
|
|
505
503
|
- ⬜ ANPR (Detect, Crop, OCR, MQTT)
|
|
@@ -432,7 +432,7 @@ Nodes can:
|
|
|
432
432
|
|
|
433
433
|
### Example Flow Documentation Needed
|
|
434
434
|
- ⬜ Bird seed level monitor
|
|
435
|
-
- ⬜ Capture data and send to Roboflow
|
|
435
|
+
- ⬜ Capture data and send to Roboflow
|
|
436
436
|
- ⬜ Track objects time in zone
|
|
437
437
|
- ⬜ Live VLMs
|
|
438
438
|
- ⬜ ANPR (Detect, Crop, OCR, MQTT)
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.2.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 2,
|
|
21
|
+
__version__ = version = '0.2.1'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 1)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'g46a6184ff'
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
from .engines.base_engine import BaseInferenceEngine
|
|
2
|
+
from .inference_engine_factory import InferenceEngineFactory
|
|
3
|
+
|
|
4
|
+
# Don't import specific engines directly - let the factory auto-discover them.
|
|
5
|
+
# This prevents import errors when an engine's optional dependencies aren't installed.
|
|
@@ -57,7 +57,7 @@ class UltralyticsEngine(BaseInferenceEngine):
|
|
|
57
57
|
super().__init__(**kwargs)
|
|
58
58
|
self.model_path = kwargs.get('model_path', None)
|
|
59
59
|
self.device = kwargs.get('device', "CPU") # Default device
|
|
60
|
-
self.output_format = kwargs.get('output_format', "
|
|
60
|
+
self.output_format = kwargs.get('output_format', "dict") # Default output format
|
|
61
61
|
self.task = kwargs.get('task', 'detect') # Default task for YOLO models
|
|
62
62
|
self.deployment = None
|
|
63
63
|
self.use_openvino = False
|
|
@@ -809,7 +809,7 @@ except Exception as e:
|
|
|
809
809
|
result_types = list(set([r.get("type", "unknown") for r in json_results]))
|
|
810
810
|
primary_type = result_types[0] if len(result_types) == 1 else self.task
|
|
811
811
|
|
|
812
|
-
# TODO: fix inconsistency with image and original_image between
|
|
812
|
+
# TODO: fix inconsistency with image and original_image between engines
|
|
813
813
|
final_results = {
|
|
814
814
|
"task_type": primary_type,
|
|
815
815
|
"num_detections": len(json_results),
|
|
@@ -151,7 +151,6 @@ class InferenceEngineFactory:
|
|
|
151
151
|
|
|
152
152
|
Examples:
|
|
153
153
|
- UltralyticsEngine -> ultralytics
|
|
154
|
-
- GetiEngine -> geti
|
|
155
154
|
- CustomObjectDetectionEngine -> custom_object_detection
|
|
156
155
|
- MyAIEngine -> my_ai
|
|
157
156
|
"""
|
|
@@ -191,7 +190,7 @@ class InferenceEngineFactory:
|
|
|
191
190
|
Create an inference engine instance.
|
|
192
191
|
|
|
193
192
|
Args:
|
|
194
|
-
engine_type: Type of engine ('ultralytics',
|
|
193
|
+
engine_type: Type of engine ('ultralytics', etc.)
|
|
195
194
|
**kwargs: Additional parameters for the specific engine type
|
|
196
195
|
|
|
197
196
|
Returns:
|
|
@@ -306,12 +305,6 @@ class InferenceEngineFactory:
|
|
|
306
305
|
'primary': True,
|
|
307
306
|
'dependencies': ['ultralytics', 'torch', 'torchvision']
|
|
308
307
|
},
|
|
309
|
-
'geti': {
|
|
310
|
-
'icon': 'fas fa-microchip',
|
|
311
|
-
'description': 'Geti computer vision platform',
|
|
312
|
-
'primary': True,
|
|
313
|
-
'dependencies': ['geti-sdk']
|
|
314
|
-
},
|
|
315
308
|
'pass': {
|
|
316
309
|
'icon': 'fas fa-forward',
|
|
317
310
|
'description': 'Pass-through engine for testing',
|
|
@@ -518,7 +511,6 @@ if __name__ == "__main__":
|
|
|
518
511
|
# Test class name to key conversion
|
|
519
512
|
test_names = [
|
|
520
513
|
"UltralyticsEngine",
|
|
521
|
-
"GetiEngine",
|
|
522
514
|
"CustomObjectDetectionEngine",
|
|
523
515
|
"MyAIEngine",
|
|
524
516
|
"SimpleEngine",
|
{pynode_flow-0.2.0 → pynode_flow-0.2.1}/pynode/nodes/InferenceNode/InferenceEngine/readme.md
RENAMED
|
@@ -18,7 +18,7 @@ from InferenceEngine.inference_engine_factory import InferenceEngineFactory
|
|
|
18
18
|
|
|
19
19
|
# Create built-in engines
|
|
20
20
|
engine = InferenceEngineFactory('ultralytics')
|
|
21
|
-
|
|
21
|
+
onnx_engine = InferenceEngineFactory('onnx')
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
### Runtime Registration
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""
|
|
3
|
-
Utilities for
|
|
4
|
-
Uses official Geti SDK data models for proper format compliance.
|
|
5
|
-
Supports conversion between Ultralytics and Geti inference result formats.
|
|
3
|
+
Utilities for summarising and converting inference engine result formats.
|
|
6
4
|
"""
|
|
7
5
|
|
|
8
6
|
from typing import Dict, List, Any, Optional
|
|
@@ -10,24 +8,7 @@ import logging
|
|
|
10
8
|
|
|
11
9
|
logger = logging.getLogger(__name__)
|
|
12
10
|
|
|
13
|
-
# Import Geti SDK data models
|
|
14
|
-
try:
|
|
15
|
-
from geti_sdk.data_models.shapes import Rectangle as GetiRectangle, ShapeType as GetiShapeType
|
|
16
|
-
from geti_sdk.data_models.predictions import Prediction
|
|
17
|
-
from geti_sdk.data_models.label import ScoredLabel
|
|
18
|
-
from geti_sdk.data_models.annotations import Annotation
|
|
19
|
-
from geti_sdk.data_models.annotation_scene import AnnotationScene
|
|
20
11
|
|
|
21
|
-
GETI_SDK_AVAILABLE = True
|
|
22
|
-
|
|
23
|
-
except ImportError as e:
|
|
24
|
-
logger.warning(f"Geti SDK not available: {e}. Using fallback Rectangle class.")
|
|
25
|
-
GETI_SDK_AVAILABLE = False
|
|
26
|
-
GetiRectangle = None
|
|
27
|
-
GetiShapeType = None
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
# Fallback classes that work whether SDK is available or not
|
|
31
12
|
class ShapeType:
|
|
32
13
|
RECTANGLE = "RECTANGLE"
|
|
33
14
|
|
|
@@ -39,41 +20,38 @@ class Rectangle:
|
|
|
39
20
|
self.width = width
|
|
40
21
|
self.height = height
|
|
41
22
|
self.type = type
|
|
42
|
-
|
|
23
|
+
|
|
43
24
|
def __repr__(self):
|
|
44
25
|
return f"Rectangle(x={self.x}, y={self.y}, width={self.width}, height={self.height}, type=<ShapeType.{self.type}: '{self.type}'>)"
|
|
45
26
|
|
|
46
27
|
|
|
47
28
|
def create_rectangle(x: float, y: float, width: float, height: float):
|
|
48
|
-
"""Create a Rectangle
|
|
49
|
-
|
|
50
|
-
return GetiRectangle(x=int(x), y=int(y), width=int(width), height=int(height))
|
|
51
|
-
else:
|
|
52
|
-
return Rectangle(x=x, y=y, width=width, height=height, type=ShapeType.RECTANGLE)
|
|
29
|
+
"""Create a Rectangle."""
|
|
30
|
+
return Rectangle(x=x, y=y, width=width, height=height, type=ShapeType.RECTANGLE)
|
|
53
31
|
|
|
54
32
|
|
|
55
33
|
def extract_detections_summary(result: Dict[str, Any]) -> Dict[str, Any]:
|
|
56
34
|
"""
|
|
57
35
|
Extract a simplified summary of detections from any result format.
|
|
58
|
-
|
|
36
|
+
|
|
59
37
|
Args:
|
|
60
38
|
result: Inference result from any supported engine
|
|
61
|
-
|
|
39
|
+
|
|
62
40
|
Returns:
|
|
63
41
|
Dict with simplified detection summary
|
|
64
42
|
"""
|
|
65
43
|
if not result.get('success', False):
|
|
66
44
|
return {
|
|
67
|
-
'engine': 'unknown',
|
|
68
|
-
'detection_count': 0,
|
|
69
|
-
'classes_detected': [],
|
|
70
|
-
'confidence_range': (0.0, 0.0),
|
|
45
|
+
'engine': 'unknown',
|
|
46
|
+
'detection_count': 0,
|
|
47
|
+
'classes_detected': [],
|
|
48
|
+
'confidence_range': (0.0, 0.0),
|
|
71
49
|
'detections': []
|
|
72
50
|
}
|
|
73
|
-
|
|
51
|
+
|
|
74
52
|
engine = result.get('results', {}).get('engine', 'unknown')
|
|
75
53
|
detections = []
|
|
76
|
-
|
|
54
|
+
|
|
77
55
|
if engine == 'ultralytics':
|
|
78
56
|
ultra_results = result.get('results', {}).get('results', [])
|
|
79
57
|
for result_item in ultra_results:
|
|
@@ -83,25 +61,11 @@ def extract_detections_summary(result: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
83
61
|
'confidence': detection.get('confidence', 0.0),
|
|
84
62
|
'bbox': detection.get('bbox', [])
|
|
85
63
|
})
|
|
86
|
-
|
|
87
|
-
elif engine == 'geti':
|
|
88
|
-
predictions = result.get('results', {}).get('results', {}).get('predictions', [])
|
|
89
|
-
for prediction in predictions:
|
|
90
|
-
shape = prediction.get('shape')
|
|
91
|
-
bbox = []
|
|
92
|
-
if shape and hasattr(shape, 'x'):
|
|
93
|
-
bbox = [shape.x, shape.y, shape.x + shape.width, shape.y + shape.height]
|
|
94
|
-
|
|
95
|
-
detections.append({
|
|
96
|
-
'class_name': prediction.get('label', 'unknown'),
|
|
97
|
-
'confidence': prediction.get('confidence', 0.0),
|
|
98
|
-
'bbox': bbox
|
|
99
|
-
})
|
|
100
|
-
|
|
64
|
+
|
|
101
65
|
classes_detected = list(set(d['class_name'] for d in detections))
|
|
102
66
|
confidences = [d['confidence'] for d in detections]
|
|
103
67
|
confidence_range = (min(confidences, default=0.0), max(confidences, default=0.0))
|
|
104
|
-
|
|
68
|
+
|
|
105
69
|
return {
|
|
106
70
|
'engine': engine,
|
|
107
71
|
'detection_count': len(detections),
|
|
@@ -114,8 +78,7 @@ def extract_detections_summary(result: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
114
78
|
# Export all functions
|
|
115
79
|
__all__ = [
|
|
116
80
|
'Rectangle',
|
|
117
|
-
'ShapeType',
|
|
81
|
+
'ShapeType',
|
|
118
82
|
'create_rectangle',
|
|
119
83
|
'extract_detections_summary',
|
|
120
|
-
'GETI_SDK_AVAILABLE'
|
|
121
84
|
]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Inference Node - Performs inference using multiple backends (Ultralytics,
|
|
2
|
+
Inference Node - Performs inference using multiple backends (Ultralytics, ONNX, etc.)
|
|
3
3
|
Supports engine selection, model file upload, target hardware selection, and inference.
|
|
4
4
|
"""
|
|
5
5
|
|
|
@@ -14,7 +14,7 @@ from pynode.nodes.base_node import BaseNode, Info, MessageKeys
|
|
|
14
14
|
logger = logging.getLogger(__name__)
|
|
15
15
|
|
|
16
16
|
_info = Info()
|
|
17
|
-
_info.add_text("Performs object detection and inference using multiple backends including Ultralytics YOLO
|
|
17
|
+
_info.add_text("Performs object detection and inference using multiple backends including Ultralytics YOLO and ONNX Runtime.")
|
|
18
18
|
_info.add_header("Inputs")
|
|
19
19
|
_info.add_bullets(("Input 0:", "Image message with 'image' field (base64 or numpy array)"))
|
|
20
20
|
_info.add_header("Outputs")
|
|
@@ -23,7 +23,7 @@ _info.add_bullets(
|
|
|
23
23
|
)
|
|
24
24
|
_info.add_header("Configuration")
|
|
25
25
|
_info.add_bullets(
|
|
26
|
-
("Engine Type:", "Select inference backend (Ultralytics,
|
|
26
|
+
("Engine Type:", "Select inference backend (Ultralytics, ONNX, etc.)"),
|
|
27
27
|
("Model File:", "Path to model file (.pt, .onnx, .xml, .zip)"),
|
|
28
28
|
("Target Hardware:", "CPU, CUDA GPU, or Intel OpenVINO devices"),
|
|
29
29
|
("Confidence:", "Minimum confidence threshold (0.0-1.0)"),
|
|
@@ -43,7 +43,7 @@ except ImportError:
|
|
|
43
43
|
class InferenceNode(BaseNode):
|
|
44
44
|
"""
|
|
45
45
|
Inference Node - performs inference using multiple backends.
|
|
46
|
-
Supports Ultralytics YOLO,
|
|
46
|
+
Supports Ultralytics YOLO, ONNX, and other inference engines.
|
|
47
47
|
"""
|
|
48
48
|
# Visual properties
|
|
49
49
|
display_name = 'Inference'
|
|
@@ -83,7 +83,6 @@ class InferenceNode(BaseNode):
|
|
|
83
83
|
# Fallback to common engines
|
|
84
84
|
return [
|
|
85
85
|
{'value': 'ultralytics', 'label': 'Ultralytics YOLO'},
|
|
86
|
-
{'value': 'geti', 'label': 'Geti'},
|
|
87
86
|
{'value': 'onnx', 'label': 'ONNX Runtime'},
|
|
88
87
|
{'value': 'pass', 'label': 'Pass-through (Testing)'}
|
|
89
88
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pynode-flow
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Python based Node-RED-like visual workflow system
|
|
5
5
|
Author: olkham
|
|
6
6
|
License-Expression: MIT
|
|
@@ -38,7 +38,6 @@ Requires-Dist: framesource[full]; extra == "camera"
|
|
|
38
38
|
Provides-Extra: inference
|
|
39
39
|
Requires-Dist: pynode-flow[vision]; extra == "inference"
|
|
40
40
|
Requires-Dist: onnxruntime; extra == "inference"
|
|
41
|
-
Requires-Dist: geti-sdk>=2.0.0; extra == "inference"
|
|
42
41
|
Provides-Extra: vlm
|
|
43
42
|
Requires-Dist: pynode-flow[vision]; extra == "vlm"
|
|
44
43
|
Requires-Dist: transformers>=4.50.0; extra == "vlm"
|
|
@@ -46,7 +45,6 @@ Requires-Dist: qwen-vl-utils>=0.0.8; extra == "vlm"
|
|
|
46
45
|
Requires-Dist: Pillow>=9.0.0; extra == "vlm"
|
|
47
46
|
Provides-Extra: upload
|
|
48
47
|
Requires-Dist: roboflow>=1.0.0; extra == "upload"
|
|
49
|
-
Requires-Dist: geti-sdk>=2.0.0; extra == "upload"
|
|
50
48
|
Provides-Extra: discovery
|
|
51
49
|
Requires-Dist: zeroconf>=0.38.0; extra == "discovery"
|
|
52
50
|
Provides-Extra: full
|
|
@@ -499,7 +497,7 @@ Nodes can:
|
|
|
499
497
|
|
|
500
498
|
### Example Flow Documentation Needed
|
|
501
499
|
- ⬜ Bird seed level monitor
|
|
502
|
-
- ⬜ Capture data and send to Roboflow
|
|
500
|
+
- ⬜ Capture data and send to Roboflow
|
|
503
501
|
- ⬜ Track objects time in zone
|
|
504
502
|
- ⬜ Live VLMs
|
|
505
503
|
- ⬜ ANPR (Detect, Crop, OCR, MQTT)
|
|
@@ -91,9 +91,6 @@ pynode/nodes/FunctionNode/function_node.py
|
|
|
91
91
|
pynode/nodes/FunctionNode/requirements.txt
|
|
92
92
|
pynode/nodes/GateNode/gate_node.py
|
|
93
93
|
pynode/nodes/GateNode/requirements.txt
|
|
94
|
-
pynode/nodes/GetiUploadNode/__init__.py
|
|
95
|
-
pynode/nodes/GetiUploadNode/geti_upload_node.py
|
|
96
|
-
pynode/nodes/GetiUploadNode/requirements.txt
|
|
97
94
|
pynode/nodes/ImageFormatNode/__init__.py
|
|
98
95
|
pynode/nodes/ImageFormatNode/image_format_node.py
|
|
99
96
|
pynode/nodes/ImageFormatNode/requirements.txt
|
|
@@ -113,7 +110,6 @@ pynode/nodes/InferenceNode/InferenceEngine/readme.md
|
|
|
113
110
|
pynode/nodes/InferenceNode/InferenceEngine/result_converters.py
|
|
114
111
|
pynode/nodes/InferenceNode/InferenceEngine/engines/base_engine.py
|
|
115
112
|
pynode/nodes/InferenceNode/InferenceEngine/engines/example_engine_template.py
|
|
116
|
-
pynode/nodes/InferenceNode/InferenceEngine/engines/geti_engine.py
|
|
117
113
|
pynode/nodes/InferenceNode/InferenceEngine/engines/onnx_engine.py
|
|
118
114
|
pynode/nodes/InferenceNode/InferenceEngine/engines/pass_engine.py
|
|
119
115
|
pynode/nodes/InferenceNode/InferenceEngine/engines/ultralytics_engine.py
|