diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index d8e92384..00000000 --- a/.gitattributes +++ /dev/null @@ -1,3 +0,0 @@ -ai-ref-kits/meter_reader/model/deeplabv3+.onnx filter=lfs diff=lfs merge=lfs -text -ai-ref-kits/meter_reader/model/yolov8.onnx filter=lfs diff=lfs merge=lfs -text -*.onnx filter=lfs diff=lfs merge=lfs -text diff --git a/.github/reusable-steps/categorize-projects/action.yml b/.github/reusable-steps/categorize-projects/action.yml index 152c1ded..d254780c 100644 --- a/.github/reusable-steps/categorize-projects/action.yml +++ b/.github/reusable-steps/categorize-projects/action.yml @@ -6,6 +6,8 @@ inputs: outputs: notebook: value: ${{ steps.group-subprojects.outputs.notebook }} + python: + value: ${{ steps.group-subprojects.outputs.python }} gradio: value: ${{ steps.group-subprojects.outputs.gradio }} webcam: @@ -21,6 +23,7 @@ runs: shell: bash run: | notebook=() + python=() gradio=() webcam=() js=() @@ -34,15 +37,19 @@ runs: gradio+=("$dir") elif [ -f "$dir/main.py" ] && grep -q -- "--stream" "$dir/main.py"; then webcam+=("$dir") + else + python+=("$dir") fi done notebook_json=$(printf '%s\n' "${notebook[@]}" | jq -R -s -c 'split("\n") | map(select(length > 0))') + python_json=$(printf '%s\n' "${python[@]}" | jq -R -s -c 'split("\n") | map(select(length > 0))') gradio_json=$(printf '%s\n' "${gradio[@]}" | jq -R -s -c 'split("\n") | map(select(length > 0))') webcam_json=$(printf '%s\n' "${webcam[@]}" | jq -R -s -c 'split("\n") | map(select(length > 0))') js_json=$(printf '%s\n' "${js[@]}" | jq -R -s -c 'split("\n") | map(select(length > 0))') echo "notebook=$notebook_json" >> $GITHUB_OUTPUT + echo "python=$python_json" >> $GITHUB_OUTPUT echo "gradio=$gradio_json" >> $GITHUB_OUTPUT echo "webcam=$webcam_json" >> $GITHUB_OUTPUT echo "js=$js_json" >> $GITHUB_OUTPUT @@ -50,6 +57,7 @@ runs: shell: bash run: | echo "Notebook subprojects: ${{ steps.group-subprojects.outputs.notebook }}" + echo "Python subprojects: ${{ steps.group-subprojects.outputs.python }}" echo "Gradio subprojects: ${{ steps.group-subprojects.outputs.gradio }}" echo "Webcam subprojects: ${{ steps.group-subprojects.outputs.webcam }}" echo "JS subprojects: ${{ steps.group-subprojects.outputs.js }}" diff --git a/.github/reusable-steps/setup-python/action.yml b/.github/reusable-steps/setup-python/action.yml index 472357aa..6b8fd0e6 100644 --- a/.github/reusable-steps/setup-python/action.yml +++ b/.github/reusable-steps/setup-python/action.yml @@ -9,6 +9,10 @@ inputs: runs: using: 'composite' steps: + - name: Download all repo files + shell: bash + run: | + git lfs -X= -I=* pull - name: Download sample video file shell: bash run: | diff --git a/.github/workflows/sanity-check-kits.yml b/.github/workflows/sanity-check-kits.yml index eca54552..3663fd13 100644 --- a/.github/workflows/sanity-check-kits.yml +++ b/.github/workflows/sanity-check-kits.yml @@ -22,6 +22,7 @@ jobs: outputs: gradio: ${{ steps.categorize-subprojects.outputs.gradio }} webcam: ${{ steps.categorize-subprojects.outputs.webcam }} + python: ${{ steps.categorize-subprojects.outputs.python }} notebook: ${{ steps.categorize-subprojects.outputs.notebook }} steps: - name: Check out code @@ -93,6 +94,29 @@ jobs: command: python main.py --stream sample_video.mp4 project: ${{ matrix.subproject }} + python: + needs: find-subprojects + if: ${{ needs.find-subprojects.outputs.python != '[]' }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + python: ["3.9", "3.12"] + subproject: ${{ fromJson(needs.find-subprojects.outputs.python) }} + steps: + - uses: actions/checkout@v4 + - uses: ./.github/reusable-steps/setup-os + - uses: ./.github/reusable-steps/setup-python + with: + python: ${{ matrix.python }} + project: ${{ matrix.subproject }} + - uses: ./.github/reusable-steps/timeouted-action + name: Run Python + with: + command: python main.py + project: ${{ matrix.subproject }} + notebook: needs: find-subprojects if: ${{ needs.find-subprojects.outputs.notebook != '[]' }} diff --git a/ai_ref_kits/meter_reader/.gitattributes b/ai_ref_kits/meter_reader/.gitattributes new file mode 100644 index 00000000..0bb75f73 --- /dev/null +++ b/ai_ref_kits/meter_reader/.gitattributes @@ -0,0 +1 @@ +*.onnx filter=lfs diff=lfs merge=lfs -text diff --git a/ai_ref_kits/meter_reader/README.md b/ai_ref_kits/meter_reader/README.md index 464b948c..ad9a317e 100644 --- a/ai_ref_kits/meter_reader/README.md +++ b/ai_ref_kits/meter_reader/README.md @@ -41,7 +41,7 @@ Now, let's dive into the steps, starting with installing Python. ## Installing Prerequisites -This project requires Python 3.7 or higher. If you don't have Python installed on your machine, go to https://www.python.org/downloads/ and download the latest version for your operating system. Follow the prompts to install Python, making sure to check the option to add Python to your PATH environment variable. +This project requires Python 3.9 or higher. If you don't have Python installed on your machine, go to https://www.python.org/downloads/ and download the latest version for your operating system. Follow the prompts to install Python, making sure to check the option to add Python to your PATH environment variable. ## Setting up your Environment diff --git a/ai_ref_kits/meter_reader/analog/base.py b/ai_ref_kits/meter_reader/analog/base.py index 4e043fb0..b5afed74 100644 --- a/ai_ref_kits/meter_reader/analog/base.py +++ b/ai_ref_kits/meter_reader/analog/base.py @@ -5,7 +5,7 @@ import openvino.runtime as ov -class analog_base(object): +class AnalogBase(object): def __init__(self, config, output_dir): self.METER_SHAPE = [512, 512] self.CIRCLE_CENTER = [256, 256] diff --git a/ai_ref_kits/meter_reader/analog/paddle.py b/ai_ref_kits/meter_reader/analog/paddle.py index 827393aa..c3507b2a 100644 --- a/ai_ref_kits/meter_reader/analog/paddle.py +++ b/ai_ref_kits/meter_reader/analog/paddle.py @@ -1,10 +1,10 @@ -from analog.base import analog_base +from analog.base import AnalogBase import numpy as np import cv2 import os -class analog_paddle(analog_base): +class AnalogPaddle(AnalogBase): def __init__(self, config, output_dir): super().__init__(config, output_dir) diff --git a/ai_ref_kits/meter_reader/analog/yolo.py b/ai_ref_kits/meter_reader/analog/yolo.py index 842fbbfd..02963b38 100644 --- a/ai_ref_kits/meter_reader/analog/yolo.py +++ b/ai_ref_kits/meter_reader/analog/yolo.py @@ -1,5 +1,5 @@ from utils import tlwh_to_xyxy -from analog.base import analog_base +from analog.base import AnalogBase import numpy as np import cv2 import os @@ -7,7 +7,7 @@ sys.path.append("../") -class analog_yolo(analog_base): +class AnalogYolo(AnalogBase): def __init__(self, config, output_dir): super().__init__(config, output_dir) diff --git a/ai_ref_kits/meter_reader/main.py b/ai_ref_kits/meter_reader/main.py index dbc94446..14b58d29 100644 --- a/ai_ref_kits/meter_reader/main.py +++ b/ai_ref_kits/meter_reader/main.py @@ -1,31 +1,36 @@ -from analog.paddle import analog_paddle -from analog.yolo import analog_yolo +from analog.paddle import AnalogPaddle +from analog.yolo import AnalogYolo import argparse import cv2 import os import json -if __name__ == "__main__": - parser = argparse.ArgumentParser(add_help=False) - parser.add_argument('-h', '--help', action='help', help='Show this help message and exit.') - parser.add_argument('-i', '--input', required=True, type=str, - help='Required. Path to an image file.') - parser.add_argument('-c', '--config', required=True, type=str, - help='Required. config file path') - parser.add_argument('-t', '--task', required=True, default='analog', type=str, - help='Required. mode of meter reader, digital or analog') - args = parser.parse_args() - - output_dir = os.path.abspath(os.path.dirname(args.input)) - with open(args.config) as f: + +def main(img_path: str, config_file: str): + output_dir = os.path.abspath(os.path.dirname(img_path)) + with open(config_file) as f: config = json.load(f) if len(config["model_config"]["detector"]["model_shape"]) == 1: - meter_reader = analog_yolo(config, output_dir) + meter_reader = AnalogYolo(config, output_dir) else: - meter_reader = analog_paddle(config, output_dir) - image = cv2.imread(args.input) + meter_reader = AnalogPaddle(config, output_dir) + image = cv2.imread(img_path) det_resutls = meter_reader.detect(image) seg_resutls = meter_reader.segment(det_resutls) post_resutls = meter_reader.postprocess(seg_resutls) meter_reader.reading(post_resutls, image) - print(f"result images saved to \"{output_dir}\".") \ No newline at end of file + print(f"result images saved to \"{output_dir}\".") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(add_help=False) + parser.add_argument('-h', '--help', action='help', help='Show this help message and exit.') + parser.add_argument('-i', '--input', default="data/test.jpg", type=str, + help='Required. Path to an image file.') + parser.add_argument('-c', '--config', default="config/yolov8.json", type=str, + help='Required. config file path') + parser.add_argument('-t', '--task', default='analog', type=str, + help='Required. mode of meter reader, digital or analog') + args = parser.parse_args() + + main(args.input, args.config) diff --git a/ai_ref_kits/meter_reader/requirements.txt b/ai_ref_kits/meter_reader/requirements.txt index f1e153fb..558a8e6e 100644 --- a/ai_ref_kits/meter_reader/requirements.txt +++ b/ai_ref_kits/meter_reader/requirements.txt @@ -1,3 +1,5 @@ -openvino==2024.3.0 +openvino==2024.6.0 numpy==1.26.4 opencv-python==4.9.0.80 +requests==2.32.3 +tqdm==4.67.1 \ No newline at end of file