Milosz Wasilewski | e955837 | 2024-10-16 09:28:03 +0100 | [diff] [blame^] | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | # Copyright (C) 2024 Qualcomm Inc. |
| 3 | |
| 4 | import cv2 |
| 5 | import numpy as np |
| 6 | import requests |
| 7 | import sys |
| 8 | from argparse import ArgumentParser |
| 9 | from skimage.metrics import structural_similarity |
| 10 | |
| 11 | parser = ArgumentParser() |
| 12 | parser.add_argument("--reference", required=True, help="Reference image path") |
| 13 | auth_group = parser.add_mutually_exclusive_group() |
| 14 | auth_group.add_argument( |
| 15 | "--reference-auth-user", help="Username required to download reference image" |
| 16 | ) |
| 17 | parser.add_argument( |
| 18 | "--reference-auth-password", help="Password required to download reference image" |
| 19 | ) |
| 20 | auth_group.add_argument( |
| 21 | "--reference-auth-token", help="Token required to download reference image" |
| 22 | ) |
| 23 | parser.add_argument( |
| 24 | "--threshold", |
| 25 | required=True, |
| 26 | type=float, |
| 27 | help="Minimal threshold to pass the test. Value must be between 0 and 1", |
| 28 | ) |
| 29 | parser.add_argument( |
| 30 | "--lava", |
| 31 | default=True, |
| 32 | action="store_true", |
| 33 | help="Print results in LAVA friendly format", |
| 34 | ) |
| 35 | parser.add_argument("--no-lava", dest="lava", action="store_false") |
| 36 | group = parser.add_mutually_exclusive_group(required=True) |
| 37 | group.add_argument("--device", help="Video device to capture image from") |
| 38 | group.add_argument("--image", help="Compared image path") |
| 39 | |
| 40 | args = parser.parse_args() |
| 41 | |
| 42 | if args.threshold < 0 or args.threshold > 1: |
| 43 | print(f"Invalid threshold: {args.threshold}") |
| 44 | sys.exit(1) |
| 45 | |
| 46 | first = None |
| 47 | |
| 48 | if args.reference.startswith("http"): |
| 49 | # download reference image |
| 50 | s = requests.Session() |
| 51 | if args.reference_auth_user and args.reference_auth_password: |
| 52 | s.auth = (args.reference_auth_user, args.reference_auth_password) |
| 53 | if args.reference_auth_token: |
| 54 | s.headers.update({"Authorization": f"Token {args.reference_auth_token}"}) |
| 55 | s.stream = True |
| 56 | print(f"Retrieving reference from: {args.reference}") |
| 57 | first_resp = s.get(args.reference) |
| 58 | data = first_resp.raw.read() |
| 59 | first = cv2.imdecode(np.frombuffer(data, dtype=np.uint8), cv2.IMREAD_COLOR) |
| 60 | |
| 61 | else: |
| 62 | first = cv2.imread(args.reference) |
| 63 | |
| 64 | second = None |
| 65 | |
| 66 | if args.device is not None: |
| 67 | cam = cv2.VideoCapture(args.device) |
| 68 | |
| 69 | if not (cam.isOpened()): |
| 70 | print(f"Could not open video device {args.device}") |
| 71 | sys.exit(1) |
| 72 | |
| 73 | cam.set(cv2.CAP_PROP_FRAME_WIDTH, first.shape[1]) |
| 74 | cam.set(cv2.CAP_PROP_FRAME_HEIGHT, first.shape[0]) |
| 75 | ret, second = cam.read() |
| 76 | cam.release() |
| 77 | cv2.destroyAllWindows() |
| 78 | |
| 79 | if args.image: |
| 80 | second = cv2.imread(args.image) |
| 81 | |
| 82 | first_gray = cv2.cvtColor(first, cv2.COLOR_BGR2GRAY) |
| 83 | second_gray = cv2.cvtColor(second, cv2.COLOR_BGR2GRAY) |
| 84 | |
| 85 | score, diff = structural_similarity(first_gray, second_gray, full=True) |
| 86 | print("Similarity Score: {:.3f}%".format(score * 100)) |
| 87 | print("Required threshold: {:.3f}%".format(args.threshold * 100)) |
| 88 | if score < args.threshold: |
| 89 | print("Test fail") |
| 90 | if args.lava: |
| 91 | print("<LAVA_SIGNAL_TESTCASE TEST_CASE_ID=video_output RESULT=fail>") |
| 92 | else: |
| 93 | print("Test pass") |
| 94 | if args.lava: |
| 95 | print("<LAVA_SIGNAL_TESTCASE TEST_CASE_ID=video_output RESULT=pass>") |