commit adbb2bbce3f099019c5a670a44be5ee19c2e3b30 Author: chakcy <947105045@qq.com> Date: Fri Oct 17 14:11:33 2025 +0800 add first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac7db21 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +# Python-generated files +__pycache__/ +*.py[oc] +build/ +dist/ +wheels/ +*.egg-info + +# Virtual environments +.venv + +# result +results + +# resources +resources diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..cc1923a --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.8 diff --git a/README.md b/README.md new file mode 100644 index 0000000..160d767 --- /dev/null +++ b/README.md @@ -0,0 +1,51 @@ +# 算能盒子开发 + +[TOC] + +## 盒子环境搭建 + +### 资源包 +``` +. +│ sdcard.tar # 刷机包 +│ uv-aarch64-unknown-linux-gnu.tar.gz # uv python 项目管理工具 +``` + +### 网络 + +1. 将盒子LAN口与计算机连接,WAN口与交换机/路由器连接 + +2. 通过ssh协议与连接连接 192.168.150.1 地址操作盒子 + +3. 若无交换机/路由器条件可使用电脑网络共享 + +### python环境配置 + +在计算机上输入以下命令将 uv-aarch64-unknown-linux-gnu.tar.gz 上传到盒子的 /data 路径(linaro用户的密码为linaro) + +```sh +scp uv-aarch64-unknown-linux-gnu.tar.gz linaro@192.168.150.1:/data +``` + +解压 uv-aarch64-unkown-linux-gnu.tar.gz 并配置环境 + +```sh +tar -xzvf uv-aarch64-unknown-linux-gnu.tar.gz + +# 将 uv 和 uvx 移动到 /usr/local/bin/(需要 sudo 权限) +sudo mv uv-aarch64-unknown-linux-gnu/uv /usr/local/bin/ +sudo mv uv-aarch64-unknown-linux-gnu/uvx /usr/local/bin/ + +# 确保文件有可执行权限 +sudo chmod +x /usr/local/bin/uv +sudo chmod +x /usr/local/bin/uvx + +# 验证是否能够执行uv命令 +uv --version # uv 0.9.3 +``` + +### 运行示例 + +```sh + +``` diff --git a/main.py b/main.py new file mode 100644 index 0000000..28679cf --- /dev/null +++ b/main.py @@ -0,0 +1,11 @@ +from sophon_ai_project.yolov8_bmcv import main +from sophon_ai_project.yolov8_bmcv import argsparser + +# def main(): +# print("Hello from sophon-ai-project!") + + +if __name__ == "__main__": + args = argsparser() + main(args) + print('all done.') diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..ad081ea --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,24 @@ +[project] +name = "sophon-ai-project" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.8" +dependencies = [ + "numpy>=1.24.4", + "opencv-python-headless>=4.12.0.88", +] + + +[[tool.uv.index]] +default = true +url = "https://pypi.tuna.tsinghua.edu.cn/simple" + +[tool.hatch.build.targets.wheel] +packages = ["src/sophon_ai_project"] + +[dependency-groups] +dev = [ + "dfss>=1.10.4", + "pip>=25.0.1", +] diff --git a/scripts/download.sh b/scripts/download.sh new file mode 100755 index 0000000..1e53f5d --- /dev/null +++ b/scripts/download.sh @@ -0,0 +1,127 @@ +#!/bin/bash +scripts_dir=$(dirname $(readlink -f "$0")) + +download_bm1684x=0 +download_bm1688=0 +download_cv186x=0 +download_onnx=0 +download_ckpt=0 + +while [[ $# -gt 0 ]]; do + key="$1" + + case $key in + --BM1684X) + download_bm1684x=1 + shift 1 + ;; + --BM1688) + download_bm1688=1 + shift 1 + ;; + --CV186X) + download_cv186x=1 + shift 1 + ;; + --onnx) + download_onnx=1 + shift 1 + ;; + --ckpt) + download_ckpt=1 + shift 1 + ;; + --all) + download_bm1684x=1 + download_bm1688=1 + download_cv186x=1 + download_onnx=1 + download_ckpt=1 + shift 1 + ;; + *) + echo "Invalid option: $key" >&2 + exit 1 + ;; + :) + echo "Option -$OPTARG requires an argument." >&2 + exit 1 + ;; + esac +done + +pip3 install dfss -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade +pushd $scripts_dir +# datasets +if [ ! -d "../resources/datasets" ]; +then + mkdir -p ../resources/datasets + pushd ../resources/datasets + python3 -m dfss --url=open@sophgo.com:sophon-demo/common/test.tar.gz #test pictures + tar xvf test.tar.gz && rm test.tar.gz #in case `tar xvf xx` failed. + python3 -m dfss --url=open@sophgo.com:sophon-demo/common/coco.names #coco classnames + python3 -m dfss --url=open@sophgo.com:sophon-demo/common/coco128.tar.gz #coco 128 pictures + tar xvf coco128.tar.gz && rm coco128.tar.gz + python3 -m dfss --url=open@sophgo.com:sophon-demo/common/coco_val2017_1000.tar.gz #coco 1000 pictures and json. + tar xvf coco_val2017_1000.tar.gz && rm coco_val2017_1000.tar.gz + python3 -m dfss --url=open@sophgo.com:sophon-demo/common/test_car_person_1080P.mp4 #test video + popd + echo "datasets download!" +else + echo "Datasets folder exist! Remove it if you need to update." +fi + +# models +if [ ! -d "../resources/models" ]; +then + mkdir -p ../resources/models +fi + +pushd ../resources/models + +if [ ! -d "../resources/models/BM1684X" ]; +then + if [ $download_bm1684x == 1 ]; then + python3 -m dfss --url=open@sophgo.com:sophon-demo/YOLOv8_plus_det/BM1684X.tar.gz + tar xvf BM1684X.tar.gz && rm BM1684X.tar.gz + echo "models/BM1684X download!" + fi +else + echo "models/BM1684X folder exist! Remove it if you need to update." +fi + +if [ ! -d "../resources/models/BM1688" ]; +then + if [ $download_bm1688 == 1 ]; then + python3 -m dfss --url=open@sophgo.com:sophon-demo/YOLOv8_plus_det/BM1688.tar.gz + tar xvf BM1688.tar.gz && rm BM1688.tar.gz + echo "models/BM1688 download!" + fi +else + echo "models/BM1688 folder exist! Remove it if you need to update." +fi + +if [ ! -d "../resources/models/CV186X" ]; +then + if [ $download_cv186x == 1 ]; then + python3 -m dfss --url=open@sophgo.com:sophon-demo/YOLOv8_plus_det/CV186X.tar.gz + tar xvf CV186X.tar.gz && rm CV186X.tar.gz + echo "models/CV186X download!" + fi +else + echo "models/BM1688 folder exist! Remove it if you need to update." +fi + +if [ ! -d "../resources/models/onnx" ]; +then + if [ $download_onnx == 1 ]; then + python3 -m dfss --url=open@sophgo.com:sophon-demo/YOLOv8_plus_det/onnx.tar.gz + tar xvf onnx.tar.gz && rm onnx.tar.gz + echo "models/onnx download!" + fi +else + echo "models/onnx folder exist! Remove it if you need to update." +fi +popd + +popd \ No newline at end of file diff --git a/src/sophon_ai_project/__init__.py b/src/sophon_ai_project/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/sophon_ai_project/postprocess_numpy.py b/src/sophon_ai_project/postprocess_numpy.py new file mode 100644 index 0000000..ee82d4b --- /dev/null +++ b/src/sophon_ai_project/postprocess_numpy.py @@ -0,0 +1,190 @@ +#===----------------------------------------------------------------------===# +# +# Copyright (C) 2022 Sophgo Technologies Inc. All rights reserved. +# +# SOPHON-DEMO is licensed under the 2-Clause BSD License except for the +# third-party components. +# +#===----------------------------------------------------------------------===# +import numpy as np + +class PostProcess: + def __init__(self, conf_thresh=0.001, nms_thresh=0.7, agnostic=False, multi_label=True, max_det=300): + self.conf_thresh = conf_thresh + self.nms_thresh = nms_thresh + self.agnostic_nms = agnostic + self.multi_label = multi_label + self.max_det = max_det + self.nms = pseudo_torch_nms() + + def __call__(self, preds_batch, org_size_batch, ratios_batch, txy_batch): + """ + post-processing + :param preds_batch: list of predictions in a batch + :param org_size_batch: list of (org_img_w, org_img_h) in a batch + :param ratios_batch: list of (ratio_x, ratio_y) in a batch when resize-and-center-padding + :param txy_batch: list of (tx, ty) in a batch when resize-and-center-padding + :return: + """ + + if isinstance(preds_batch, list) and len(preds_batch) == 1: + # 1 output + dets = np.concatenate(preds_batch) + else: + print('preds_batch type: '.format(type(preds_batch))) + raise NotImplementedError + + outs = self.nms.non_max_suppression(dets, + self.conf_thresh, + self.nms_thresh, + agnostic=False, + max_det=300, + multi_label=self.multi_label, + classes=None) + + # Rescale boxes from img_size to im0 size + for det, (org_w, org_h), ratio, (tx1, ty1) in zip(outs, org_size_batch, ratios_batch, txy_batch): + if len(det): + # Rescale boxes from img_size to im0 size + coords = det[:, :4] + coords[:, [0, 2]] -= tx1 # x padding + coords[:, [1, 3]] -= ty1 # y padding + coords[:, [0, 2]] /= ratio[0] + coords[:, [1, 3]] /= ratio[1] + + coords[:, [0, 2]] = coords[:, [0, 2]].clip(0, org_w - 1) # x1, x2 + coords[:, [1, 3]] = coords[:, [1, 3]].clip(0, org_h - 1) # y1, y2 + + det[:, :4] = coords + + return outs + +# numpy multiclass nms implementation from original yolov5 repo torch implementation +class pseudo_torch_nms: + def nms_boxes(self, boxes, scores, iou_thres): + x = boxes[:, 0] + y = boxes[:, 1] + w = boxes[:, 2] - boxes[:, 0] + h = boxes[:, 3] - boxes[:, 1] + + areas = w * h + order = scores.argsort()[::-1] + + keep = [] + while order.size > 0: + i = order[0] + keep.append(i) + + xx1 = np.maximum(x[i], x[order[1:]]) + yy1 = np.maximum(y[i], y[order[1:]]) + xx2 = np.minimum(x[i] + w[i], x[order[1:]] + w[order[1:]]) + yy2 = np.minimum(y[i] + h[i], y[order[1:]] + h[order[1:]]) + + w1 = np.maximum(0.0, xx2 - xx1 + 0.00001) + h1 = np.maximum(0.0, yy2 - yy1 + 0.00001) + inter = w1 * h1 + + ovr = inter / (areas[i] + areas[order[1:]] - inter) + inds = np.where(ovr <= iou_thres)[0] + order = order[inds + 1] + keep = np.array(keep) + return keep + + def xywh2xyxy(self, x): + # Convert nx4 boxes from [x, y, w, h] to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-right + y = x.copy() if isinstance(x, np.ndarray) else np.copy(x) + y[:, 0] = x[:, 0] - x[:, 2] / 2 # top left x + y[:, 1] = x[:, 1] - x[:, 3] / 2 # top left y + y[:, 2] = x[:, 0] + x[:, 2] / 2 # bottom right x + y[:, 3] = x[:, 1] + x[:, 3] / 2 # bottom right y + return y + + def nms(self, pred, conf_thres=0.001, iou_thres=0.5, agnostic=False, max_det=1000): + return self.non_max_suppression(pred, conf_thres, iou_thres, + classes=None, + agnostic=agnostic, + multi_label=True, + max_det=max_det) + + def non_max_suppression(self, + prediction, + conf_thres=0.25, + iou_thres=0.5, + classes=None, + agnostic=False, + multi_label=False, + labels=(), + max_det=300, + nm=0): + """Non-Maximum Suppression (NMS) on inference results to reject overlapping bounding boxes + + Returns: + list of detections, on (n,6) tensor per image [xyxy, conf, cls] + """ + + bs = prediction.shape[0] # batch size + nc = prediction.shape[2] - nm - 4 # number of classes + mi = 4 + nc # mask start index + xc = prediction[:, :, 4:mi].max(2) > conf_thres # candidates + + # Checks + # assert 0 <= conf_thres <= 1, f'Invalid Confidence threshold {conf_thres}, valid values are between 0.0 and 1.0' + # assert 0 <= iou_thres <= 1, f'Invalid IoU {iou_thres}, valid values are between 0.0 and 1.0' + + # Settings + max_wh = 7680 # (pixels) maximum box width and height + max_nms = 30000 # maximum number of boxes into torchvision.ops.nms() + multi_label &= nc > 1 # multiple labels per box (adds 0.5ms/img) + + # output = [torch.zeros((0, 6), device=prediction.device)] * bs + output = [np.zeros((0, 6 + nm))] * bs + for xi, x in enumerate(prediction): # image index, image inference + # Apply constraints + # x[((x[..., 2:4] < min_wh) | (x[..., 2:4] > max_wh)).any(1), 4] = 0 # width-height + x = x[xc[xi]] # confidence + + # If none remain process next image + if not x.shape[0]: + continue + + # Detections matrix nx6 (xyxy, conf, cls) + box, cls, mask = x[:,:4], x[:, 4:nc+4], x[:, nc+4:] + + # Box (center x, center y, width, height) to (x1, y1, x2, y2) + box = self.xywh2xyxy(box) + + # Detections matrix nx6 (xyxy, conf, cls) + if multi_label: + i, j = (cls > conf_thres).nonzero() + x = np.concatenate((box[i], x[i, 4 + j, None], j[:, None].astype(np.float32), mask[i]), 1) + else: # best class only + conf = cls.max(1, keepdims=True) + j_argmax = cls.argmax(1) + j = j_argmax if j_argmax.shape == x[:, 5:].shape else \ + np.expand_dims(j_argmax, 1) # for argmax(axis, keepdims=True) + x = np.concatenate((box, conf, j.astype(np.float32), mask), 1)[conf.reshape(-1) > conf_thres] + + # Check shape + n = x.shape[0] # number of boxes + if not n: # no boxes + continue + # elif n > max_nms: # excess boxes + # x_argsort = np.argsort(x[:, 4])[:max_nms] # sort by confidence + # x = x[x_argsort] + x_argsort = np.argsort(x[:, 4])[::-1][:max_nms] # sort by confidence + x = x[x_argsort] + # Batched NMS + c = x[:, 5:6] * (0 if agnostic else max_wh) # classes + boxes, scores = x[:, :4] + c, x[:, 4] # boxes (offset by class), scores + + ############################################# + # i = torchvision.ops.nms(boxes, scores, iou_thres) # NMS + i = self.nms_boxes(boxes, scores, iou_thres) + ############################################ + + if i.shape[0] > max_det: # limit detections + i = i[:max_det] + + output[xi] = x[i] + + return output diff --git a/src/sophon_ai_project/utils.py b/src/sophon_ai_project/utils.py new file mode 100644 index 0000000..279b7c1 --- /dev/null +++ b/src/sophon_ai_project/utils.py @@ -0,0 +1,125 @@ +#===----------------------------------------------------------------------===# +# +# Copyright (C) 2022 Sophgo Technologies Inc. All rights reserved. +# +# SOPHON-DEMO is licensed under the 2-Clause BSD License except for the +# third-party components. +# +#===----------------------------------------------------------------------===# +import os +import sys +import numpy as np +import cv2 + +COCO_CLASSES = ('background', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', + 'train', 'truck', 'boat', 'traffic light', 'fire hydrant', + 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', + 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', + 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', + 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', + 'baseball glove', 'skateboard', 'surfboard', 'tennis racket', + 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', + 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', + 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch', + 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', + 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', + 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', + 'scissors', 'teddy bear', 'hair drier', 'toothbrush') + +COLORS = [ + [56, 0, 255], + [226, 255, 0], + [0, 94, 255], + [0, 37, 255], + [0, 255, 94], + [255, 226, 0], + [0, 18, 255], + [255, 151, 0], + [170, 0, 255], + [0, 255, 56], + [255, 0, 75], + [0, 75, 255], + [0, 255, 169], + [255, 0, 207], + [75, 255, 0], + [207, 0, 255], + [37, 0, 255], + [0, 207, 255], + [94, 0, 255], + [0, 255, 113], + [255, 18, 0], + [255, 0, 56], + [18, 0, 255], + [0, 255, 226], + [170, 255, 0], + [255, 0, 245], + [151, 255, 0], + [132, 255, 0], + [75, 0, 255], + [151, 0, 255], + [0, 151, 255], + [132, 0, 255], + [0, 255, 245], + [255, 132, 0], + [226, 0, 255], + [255, 37, 0], + [207, 255, 0], + [0, 255, 207], + [94, 255, 0], + [0, 226, 255], + [56, 255, 0], + [255, 94, 0], + [255, 113, 0], + [0, 132, 255], + [255, 0, 132], + [255, 170, 0], + [255, 0, 188], + [113, 255, 0], + [245, 0, 255], + [113, 0, 255], + [255, 188, 0], + [0, 113, 255], + [255, 0, 0], + [0, 56, 255], + [255, 0, 113], + [0, 255, 188], + [255, 0, 94], + [255, 0, 18], + [18, 255, 0], + [0, 255, 132], + [0, 188, 255], + [0, 245, 255], + [0, 169, 255], + [37, 255, 0], + [255, 0, 151], + [188, 0, 255], + [0, 255, 37], + [0, 255, 0], + [255, 0, 170], + [255, 0, 37], + [255, 75, 0], + [0, 0, 255], + [255, 207, 0], + [255, 0, 226], + [255, 245, 0], + [188, 255, 0], + [0, 255, 18], + [0, 255, 75], + [0, 255, 151], + [255, 56, 0], + [245, 255, 0], + ] + +def is_img(file_name): + """judge the file is available image or not + Args: + file_name (str): input file name + Returns: + (bool) : whether the file is available image + """ + fmt = os.path.splitext(file_name)[-1] + if isinstance(fmt, str) and fmt.lower() in ['.jpg','.png','.jpeg','.bmp','.jpeg','.webp']: + return True + else: + return False + diff --git a/src/sophon_ai_project/yolov8_bmcv.py b/src/sophon_ai_project/yolov8_bmcv.py new file mode 100644 index 0000000..3dbda75 --- /dev/null +++ b/src/sophon_ai_project/yolov8_bmcv.py @@ -0,0 +1,393 @@ +#===----------------------------------------------------------------------===# +# +# Copyright (C) 2022 Sophgo Technologies Inc. All rights reserved. +# +# SOPHON-DEMO is licensed under the 2-Clause BSD License except for the +# third-party components. +# +#===----------------------------------------------------------------------===# +import os +import time +import json +import argparse +import numpy as np +import sophon.sail as sail +from .postprocess_numpy import PostProcess +from .utils import COCO_CLASSES, COLORS +import logging +logging.basicConfig(level=logging.INFO) + +class YOLOv8: + def __init__(self, args): + # load bmodel + self.net = sail.Engine(args.bmodel, args.dev_id, sail.IOMode.SYSO) + logging.debug("load {} success!".format(args.bmodel)) + self.handle = sail.Handle(args.dev_id) + self.bmcv = sail.Bmcv(self.handle) + self.graph_name = self.net.get_graph_names()[0] + + # get input + self.input_name = self.net.get_input_names(self.graph_name)[0] + self.input_dtype= self.net.get_input_dtype(self.graph_name, self.input_name) + self.img_dtype = self.bmcv.get_bm_image_data_format(self.input_dtype) + self.input_scale = self.net.get_input_scale(self.graph_name, self.input_name) + self.input_shape = self.net.get_input_shape(self.graph_name, self.input_name) + self.input_shapes = {self.input_name: self.input_shape} + + # get output + self.output_names = self.net.get_output_names(self.graph_name) + self.output_tensors = {} + self.output_scales = {} + for output_name in self.output_names: + output_shape = self.net.get_output_shape(self.graph_name, output_name) + output_dtype = self.net.get_output_dtype(self.graph_name, output_name) + output_scale = self.net.get_output_scale(self.graph_name, output_name) + output = sail.Tensor(self.handle, output_shape, output_dtype, True, True) + self.output_tensors[output_name] = output + self.output_scales[output_name] = output_scale + if(output_shape[1] < output_shape[2]): + raise ValueError('Only support OPT model, please refer to the docs/YOLOv8_Export_Guide.md to export OPT model.') + # check batch size + self.batch_size = self.input_shape[0] + suppoort_batch_size = [1, 2, 3, 4, 8, 16, 32, 64, 128, 256] + if self.batch_size not in suppoort_batch_size: + raise ValueError('batch_size must be {} for bmcv, but got {}'.format(suppoort_batch_size, self.batch_size)) + self.net_h = self.input_shape[2] + self.net_w = self.input_shape[3] + + # init preprocess + self.use_resize_padding = True + self.use_vpp = False + self.ab = [x * self.input_scale / 255. for x in [1, 0, 1, 0, 1, 0]] + + # init postprocess + self.conf_thresh = args.conf_thresh + self.nms_thresh = args.nms_thresh + self.agnostic = False + self.multi_label = False + self.max_det = 300 + + self.postprocess = PostProcess( + conf_thresh=self.conf_thresh, + nms_thresh=self.nms_thresh, + agnostic=self.agnostic, + multi_label=self.multi_label, + max_det=self.max_det, + ) + + # init time + self.preprocess_time = 0.0 + self.inference_time = 0.0 + self.postprocess_time = 0.0 + + def init(self): + self.preprocess_time = 0.0 + self.inference_time = 0.0 + self.postprocess_time = 0.0 + + def preprocess_bmcv(self, input_bmimg): + rgb_planar_img = sail.BMImage(self.handle, input_bmimg.height(), input_bmimg.width(), + sail.Format.FORMAT_RGB_PLANAR, sail.DATA_TYPE_EXT_1N_BYTE) + self.bmcv.convert_format(input_bmimg, rgb_planar_img) + resized_img_rgb, ratio, txy = self.resize_bmcv(rgb_planar_img) + preprocessed_bmimg = sail.BMImage(self.handle, self.net_h, self.net_w, sail.Format.FORMAT_RGB_PLANAR, self.img_dtype) + self.bmcv.convert_to(resized_img_rgb, preprocessed_bmimg, ((self.ab[0], self.ab[1]), \ + (self.ab[2], self.ab[3]), \ + (self.ab[4], self.ab[5]))) + return preprocessed_bmimg, ratio, txy + + def resize_bmcv(self, bmimg): + """ + resize for single sail.BMImage + :param bmimg: + :return: a resize image of sail.BMImage + """ + img_w = bmimg.width() + img_h = bmimg.height() + if self.use_resize_padding: + r_w = self.net_w / img_w + r_h = self.net_h / img_h + r = min(r_w, r_h) + tw = int(round(r * img_w)) + th = int(round(r * img_h)) + tx1, ty1 = self.net_w - tw, self.net_h - th # wh padding + + tx1 /= 2 # divide padding into 2 sides + ty1 /= 2 + + ratio = (r, r) + txy = (tx1, ty1) + attr = sail.PaddingAtrr() + attr.set_stx(int(round(tx1 - 0.1))) + attr.set_sty(int(round(ty1 - 0.1))) + attr.set_w(tw) + attr.set_h(th) + attr.set_r(114) + attr.set_g(114) + attr.set_b(114) + + preprocess_fn = self.bmcv.vpp_crop_and_resize_padding if self.use_vpp else self.bmcv.crop_and_resize_padding + resized_img_rgb = preprocess_fn(bmimg, 0, 0, img_w, img_h, self.net_w, self.net_h, attr, sail.bmcv_resize_algorithm.BMCV_INTER_LINEAR) + else: + r_w = self.net_w / img_w + r_h = self.net_h / img_h + ratio = (r_w, r_h) + txy = (0, 0) + preprocess_fn = self.bmcv.vpp_resize if self.use_vpp else self.bmcv.resize + resized_img_rgb = preprocess_fn(bmimg, self.net_w, self.net_h) + return resized_img_rgb, ratio, txy + + def predict(self, input_tensor, img_num): + """ + ensure output order: loc_data, conf_preds, mask_data, proto_data + Args: + input_tensor: + Returns: + """ + input_tensors = {self.input_name: input_tensor} + self.net.process(self.graph_name, input_tensors, self.input_shapes, self.output_tensors) + outputs_dict = {} + for name in self.output_names: + # outputs_dict[name] = self.output_tensors[name].asnumpy()[:img_num] * self.output_scales[name] + outputs_dict[name] = self.output_tensors[name].asnumpy()[:img_num] + # resort + out_keys = list(outputs_dict.keys()) + ord = [] + for n in self.output_names: + for i, k in enumerate(out_keys): + if n in k: + ord.append(i) + break + out = [outputs_dict[out_keys[i]] for i in ord] + return out + + def __call__(self, bmimg_list): + img_num = len(bmimg_list) + ori_size_list = [] + ratio_list = [] + txy_list = [] + if self.batch_size == 1: + ori_h, ori_w = bmimg_list[0].height(), bmimg_list[0].width() + ori_size_list.append((ori_w, ori_h)) + start_time = time.time() + preprocessed_bmimg, ratio, txy = self.preprocess_bmcv(bmimg_list[0]) + self.preprocess_time += time.time() - start_time + ratio_list.append(ratio) + txy_list.append(txy) + + input_tensor = sail.Tensor(self.handle, self.input_shape, self.input_dtype, False, False) + self.bmcv.bm_image_to_tensor(preprocessed_bmimg, input_tensor) + + else: + BMImageArray = eval('sail.BMImageArray{}D'.format(self.batch_size)) + bmimgs = BMImageArray() + for i in range(img_num): + ori_h, ori_w = bmimg_list[i].height(), bmimg_list[i].width() + ori_size_list.append((ori_w, ori_h)) + start_time = time.time() + preprocessed_bmimg, ratio, txy = self.preprocess_bmcv(bmimg_list[i]) + self.preprocess_time += time.time() - start_time + ratio_list.append(ratio) + txy_list.append(txy) + bmimgs[i] = preprocessed_bmimg.data() + input_tensor = sail.Tensor(self.handle, self.input_shape, self.input_dtype, False, False) + self.bmcv.bm_image_to_tensor(bmimgs, input_tensor) + + start_time = time.time() + outputs = self.predict(input_tensor, img_num) + self.inference_time += time.time() - start_time + + start_time = time.time() + results = self.postprocess(outputs, ori_size_list, ratio_list, txy_list) + self.postprocess_time += time.time() - start_time + + return results + +def draw_bmcv(dev_id, image, boxes, output_img_dir, file_name, cn, masks=None, classes_ids=None, conf_scores=None, isvideo=False): + bmcv = sail.Bmcv(sail.Handle(dev_id)) + img_bgr_planar = bmcv.convert_format(image) + thickness = 2 + for idx in range(len(boxes)): + x1, y1, x2, y2 = boxes[idx, :].astype(np.int32).tolist() + if classes_ids is not None: + color = np.array(COLORS[int(classes_ids[idx]) + 1]).astype(np.uint8).tolist() + else: + color = (0, 0, 255) + if (x2 - x1) <= thickness * 2 or (y2 - y1) <= thickness * 2: + logging.info("width or height too small, this rect will not be drawed: (x1={},y1={},w={},h={})".format(x1, y1, x2-x1, y2-y1)) + else: + bmcv.rectangle(img_bgr_planar, x1, y1, (x2 - x1), (y2 - y1), color, thickness) + # bmcv.putText(image, COCO_CLASSES[int(classes_ids[idx] + 1)], x1, y1, tuple(color),1.0,1) + logging.debug("class id={}, score={}, (x1={},y1={},w={},h={})".format(int(classes_ids[idx]), conf_scores[idx], x1, y1, x2-x1, y2-y1)) + if isvideo: + return img_bgr_planar + else: + bmcv.imwrite(os.path.join(output_img_dir, file_name), img_bgr_planar) + +def main(args): + # check params + if not os.path.exists(args.input): + raise FileNotFoundError('{} is not existed.'.format(args.input)) + if not os.path.exists(args.bmodel): + raise FileNotFoundError('{} is not existed.'.format(args.bmodel)) + + # creat save path + output_dir = "./results" + if not os.path.exists(output_dir): + os.mkdir(output_dir) + output_img_dir = os.path.join(output_dir, 'images') + if not os.path.exists(output_img_dir): + os.mkdir(output_img_dir) + + yolov8 = YOLOv8(args) + batch_size = yolov8.batch_size + + # warm up + # bmimg = sail.BMImage(yolov8.handle, 1080, 1920, sail.Format.FORMAT_YUV420P, sail.DATA_TYPE_EXT_1N_BYTE) + # for i in range(10): + # results = yolov8([bmimg]) + yolov8.init() + + decode_time = 0.0 + # test images + if os.path.isdir(args.input): + bmimg_list = [] + filename_list = [] + results_list = [] + cn = 0 + yolov8_handle = sail.Handle(args.dev_id) + for root, dirs, filenames in os.walk(args.input): + for filename in filenames: + if os.path.splitext(filename)[-1].lower() not in ['.jpg','.png','.jpeg','.bmp','.webp']: + continue + img_file = os.path.join(root, filename) + cn += 1 + logging.info("{}, img_file: {}".format(cn, img_file)) + # decode + start_time = time.time() + decoder = sail.Decoder(img_file, True, args.dev_id) + bmimg = sail.BMImage() + ret = decoder.read(yolov8_handle, bmimg) + if ret != 0: + logging.error("{} decode failure.".format(img_file)) + continue + decode_time += time.time() - start_time + bmimg_list.append(bmimg) + filename_list.append(filename) + if (len(bmimg_list) == batch_size or cn == len(filenames)) and len(bmimg_list): + # predict + results = yolov8(bmimg_list) + + for i, filename in enumerate(filename_list): + det = results[i] + # save image + det_draw = det[det[:, -2] > 0.1] + draw_bmcv(args.dev_id, + bmimg_list[i], + det_draw[:,:4], + output_img_dir, + filename, + cn, + masks=None, + classes_ids=det_draw[:, -1], + conf_scores=det_draw[:, -2]) + + # save result + res_dict = dict() + res_dict['image_name'] = filename + res_dict['bboxes'] = [] + for idx in range(det.shape[0]): + bbox_dict = dict() + x1, y1, x2, y2, score, category_id = det[idx] + bbox_dict['bbox'] = [float(round(x1, 3)), float(round(y1, 3)), float(round(x2 - x1,3)), float(round(y2 -y1, 3))] + bbox_dict['category_id'] = int(category_id) + bbox_dict['score'] = float(round(score,5)) + res_dict['bboxes'].append(bbox_dict) + results_list.append(res_dict) + + bmimg_list.clear() + filename_list.clear() + + # save results + if args.input[-1] == '/': + args.input = args.input[:-1] + json_name = os.path.split(args.bmodel)[-1] + "_" + os.path.split(args.input)[-1] + "_bmcv" + "_python_result.json" + with open(os.path.join(output_dir, json_name), 'w') as jf: + # json.dump(results_list, jf) + json.dump(results_list, jf, indent=4, ensure_ascii=False) + logging.info("result saved in {}".format(os.path.join(output_dir, json_name))) + + # test videos + else: + decoder = sail.Decoder(args.input, True, args.dev_id) + if not decoder.is_opened(): + raise Exception("can not open the video") + enc_params = f"width=1920:height=1080:bitrate=2000:gop=32:gop_preset=2:framerate=25" + encoder = sail.Encoder("results/output.mp4", args.dev_id, 'h264_bm', 'NV12', enc_params, 10) + + video_name = os.path.splitext(os.path.split(args.input)[1])[0] + cn = 0 + frame_list = [] + yolov8_handle = sail.Handle(args.dev_id) + end_flag = False + while not end_flag: + frame = sail.BMImage() + start_time = time.time() + ret = decoder.read(yolov8_handle, frame) + decode_time += time.time() - start_time + if ret: #differ from cv. + end_flag = True + else: + frame_list.append(frame) + if (len(frame_list) == batch_size or end_flag) and len(frame_list): + results = yolov8(frame_list) + for i, frame in enumerate(frame_list): + det = results[i] + cn += 1 + logging.info("{}, det nums: {}".format(cn, det.shape[0])) + det_draw = det[det[:, -2] > 0.1] + drawed_bmimg = draw_bmcv(args.dev_id, + frame_list[i], + det_draw[:,:4], + output_img_dir, + video_name, + cn, + masks=None, + classes_ids=det_draw[:, -1], + conf_scores=det_draw[:, -2], + isvideo=True) + encoder.video_write(drawed_bmimg) + frame_list.clear() + decoder.release() + encoder.release() + logging.info("result saved in {}".format(output_img_dir)) + + + # calculate speed + logging.info("------------------ Predict Time Info ----------------------") + decode_time = decode_time / cn + preprocess_time = yolov8.preprocess_time / cn + inference_time = yolov8.inference_time / cn + postprocess_time = yolov8.postprocess_time / cn + logging.info("decode_time(ms): {:.2f}".format(decode_time * 1000)) + logging.info("preprocess_time(ms): {:.2f}".format(preprocess_time * 1000)) + logging.info("inference_time(ms): {:.2f}".format(inference_time * 1000)) + logging.info("postprocess_time(ms): {:.2f}".format(postprocess_time * 1000)) + +def argsparser(): + parser = argparse.ArgumentParser(prog=__file__) + parser.add_argument('--input', type=str, default='../datasets/test', help='path of input') + parser.add_argument('--bmodel', type=str, default='../models/BM1684X/yolov8s_fp32_1b.bmodel', help='path of bmodel') + parser.add_argument('--dev_id', type=int, default=0, help='dev id') + parser.add_argument('--conf_thresh', type=float, default=0.25, help='confidence threshold') + parser.add_argument('--nms_thresh', type=float, default=0.7, help='nms threshold') + args = parser.parse_args() + return args + +if __name__ == "__main__": + args = argsparser() + main(args) + print('all done.') + + + diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..67c3124 --- /dev/null +++ b/uv.lock @@ -0,0 +1,249 @@ +version = 1 +revision = 3 +requires-python = ">=3.8" +resolution-markers = [ + "python_full_version >= '3.10'", + "python_full_version == '3.9.*'", + "python_full_version < '3.9'", +] + +[[package]] +name = "dfss" +version = "1.10.4" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/89/12/74e8259c586ce9ba27766d71b6c4209205e39a829337cde519872378a951/dfss-1.10.4.tar.gz", hash = "sha256:2f2713e0b8d92b9f9ec94fb83cd16f181754dbf0e9102c4cb8dc6208c81674aa", size = 8530537, upload-time = "2025-07-29T03:11:45.438Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ed/66/388cee1df022233ef157347a7275f0e80cf297bfb344e7680001e5ae2acd/dfss-1.10.4-py2.py3-none-any.whl", hash = "sha256:37bf171350dac531c7185ea5789a6d4b0e63a7cc1852c909cd333e6a2efb0ef5", size = 8556566, upload-time = "2025-07-29T03:11:34.678Z" }, +] + +[[package]] +name = "numpy" +version = "1.24.4" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +resolution-markers = [ + "python_full_version < '3.9'", +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a4/9b/027bec52c633f6556dba6b722d9a0befb40498b9ceddd29cbe67a45a127c/numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463", size = 10911229, upload-time = "2023-06-26T13:39:33.218Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/80/6cdfb3e275d95155a34659163b83c09e3a3ff9f1456880bec6cc63d71083/numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64", size = 19789140, upload-time = "2023-06-26T13:22:33.184Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/64/5f/3f01d753e2175cfade1013eea08db99ba1ee4bdb147ebcf3623b75d12aa7/numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1", size = 13854297, upload-time = "2023-06-26T13:22:59.541Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5a/b3/2f9c21d799fa07053ffa151faccdceeb69beec5a010576b8991f614021f7/numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4", size = 13995611, upload-time = "2023-06-26T13:23:22.167Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/10/be/ae5bf4737cb79ba437879915791f6f26d92583c738d7d960ad94e5c36adf/numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6", size = 17282357, upload-time = "2023-06-26T13:23:51.446Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c0/64/908c1087be6285f40e4b3e79454552a701664a079321cff519d8c7051d06/numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc", size = 12429222, upload-time = "2023-06-26T13:24:13.849Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/22/55/3d5a7c1142e0d9329ad27cece17933b0e2ab4e54ddc5c1861fbfeb3f7693/numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e", size = 14841514, upload-time = "2023-06-26T13:24:38.129Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a9/cc/5ed2280a27e5dab12994c884f1f4d8c3bd4d885d02ae9e52a9d213a6a5e2/numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810", size = 19775508, upload-time = "2023-06-26T13:25:08.882Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c0/bc/77635c657a3668cf652806210b8662e1aff84b818a55ba88257abf6637a8/numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254", size = 13840033, upload-time = "2023-06-26T13:25:33.417Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a7/4c/96cdaa34f54c05e97c1c50f39f98d608f96f0677a6589e64e53104e22904/numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7", size = 13991951, upload-time = "2023-06-26T13:25:55.725Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/22/97/dfb1a31bb46686f09e68ea6ac5c63fdee0d22d7b23b8f3f7ea07712869ef/numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5", size = 17278923, upload-time = "2023-06-26T13:26:25.658Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/35/e2/76a11e54139654a324d107da1d98f99e7aa2a7ef97cfd7c631fba7dbde71/numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d", size = 12422446, upload-time = "2023-06-26T13:26:49.302Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d8/ec/ebef2f7d7c28503f958f0f8b992e7ce606fb74f9e891199329d5f5f87404/numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694", size = 14834466, upload-time = "2023-06-26T13:27:16.029Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/11/10/943cfb579f1a02909ff96464c69893b1d25be3731b5d3652c2e0cf1281ea/numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61", size = 19780722, upload-time = "2023-06-26T13:27:49.573Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a7/ae/f53b7b265fdc701e663fbb322a8e9d4b14d9cb7b2385f45ddfabfc4327e4/numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f", size = 13843102, upload-time = "2023-06-26T13:28:12.288Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/25/6f/2586a50ad72e8dbb1d8381f837008a0321a3516dfd7cb57fc8cf7e4bb06b/numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e", size = 14039616, upload-time = "2023-06-26T13:28:35.659Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/98/5d/5738903efe0ecb73e51eb44feafba32bdba2081263d40c5043568ff60faf/numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc", size = 17316263, upload-time = "2023-06-26T13:29:09.272Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/57/8d328f0b91c733aa9aa7ee540dbc49b58796c862b4fbcb1146c701e888da/numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2", size = 12455660, upload-time = "2023-06-26T13:29:33.434Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/69/65/0d47953afa0ad569d12de5f65d964321c208492064c38fe3b0b9744f8d44/numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706", size = 14868112, upload-time = "2023-06-26T13:29:58.385Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9a/cd/d5b0402b801c8a8b56b04c1e85c6165efab298d2f0ab741c2406516ede3a/numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400", size = 19816549, upload-time = "2023-06-26T13:30:36.976Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/14/27/638aaa446f39113a3ed38b37a66243e21b38110d021bfcb940c383e120f2/numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f", size = 13879950, upload-time = "2023-06-26T13:31:01.787Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8f/27/91894916e50627476cff1a4e4363ab6179d01077d71b9afed41d9e1f18bf/numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9", size = 14030228, upload-time = "2023-06-26T13:31:26.696Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7a/7c/d7b2a0417af6428440c0ad7cb9799073e507b1a465f827d058b826236964/numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d", size = 17311170, upload-time = "2023-06-26T13:31:56.615Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/18/9d/e02ace5d7dfccee796c37b995c63322674daf88ae2f4a4724c5dd0afcc91/numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835", size = 12454918, upload-time = "2023-06-26T13:32:16.8Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/63/38/6cc19d6b8bfa1d1a459daf2b3fe325453153ca7019976274b6f33d8b5663/numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8", size = 14867441, upload-time = "2023-06-26T13:32:40.521Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a4/fd/8dff40e25e937c94257455c237b9b6bf5a30d42dd1cc11555533be099492/numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef", size = 19156590, upload-time = "2023-06-26T13:33:10.36Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/42/e7/4bf953c6e05df90c6d351af69966384fed8e988d0e8c54dad7103b59f3ba/numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a", size = 16705744, upload-time = "2023-06-26T13:33:36.703Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fc/dd/9106005eb477d022b60b3817ed5937a43dad8fd1f20b0610ea8a32fcb407/numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2", size = 14734290, upload-time = "2023-06-26T13:34:05.409Z" }, +] + +[[package]] +name = "numpy" +version = "2.0.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +resolution-markers = [ + "python_full_version == '3.9.*'", +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a9/75/10dd1f8116a8b796cb2c737b674e02d02e80454bda953fa7e65d8c12b016/numpy-2.0.2.tar.gz", hash = "sha256:883c987dee1880e2a864ab0dc9892292582510604156762362d9326444636e78", size = 18902015, upload-time = "2024-08-26T20:19:40.945Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/21/91/3495b3237510f79f5d81f2508f9f13fea78ebfdf07538fc7444badda173d/numpy-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:51129a29dbe56f9ca83438b706e2e69a39892b5eda6cedcb6b0c9fdc9b0d3ece", size = 21165245, upload-time = "2024-08-26T20:04:14.625Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/05/33/26178c7d437a87082d11019292dce6d3fe6f0e9026b7b2309cbf3e489b1d/numpy-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f15975dfec0cf2239224d80e32c3170b1d168335eaedee69da84fbe9f1f9cd04", size = 13738540, upload-time = "2024-08-26T20:04:36.784Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ec/31/cc46e13bf07644efc7a4bf68df2df5fb2a1a88d0cd0da9ddc84dc0033e51/numpy-2.0.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8c5713284ce4e282544c68d1c3b2c7161d38c256d2eefc93c1d683cf47683e66", size = 5300623, upload-time = "2024-08-26T20:04:46.491Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6e/16/7bfcebf27bb4f9d7ec67332ffebee4d1bf085c84246552d52dbb548600e7/numpy-2.0.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:becfae3ddd30736fe1889a37f1f580e245ba79a5855bff5f2a29cb3ccc22dd7b", size = 6901774, upload-time = "2024-08-26T20:04:58.173Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/a3/561c531c0e8bf082c5bef509d00d56f82e0ea7e1e3e3a7fc8fa78742a6e5/numpy-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2da5960c3cf0df7eafefd806d4e612c5e19358de82cb3c343631188991566ccd", size = 13907081, upload-time = "2024-08-26T20:05:19.098Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fa/66/f7177ab331876200ac7563a580140643d1179c8b4b6a6b0fc9838de2a9b8/numpy-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:496f71341824ed9f3d2fd36cf3ac57ae2e0165c143b55c3a035ee219413f3318", size = 19523451, upload-time = "2024-08-26T20:05:47.479Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/25/7f/0b209498009ad6453e4efc2c65bcdf0ae08a182b2b7877d7ab38a92dc542/numpy-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a61ec659f68ae254e4d237816e33171497e978140353c0c2038d46e63282d0c8", size = 19927572, upload-time = "2024-08-26T20:06:17.137Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3e/df/2619393b1e1b565cd2d4c4403bdd979621e2c4dea1f8532754b2598ed63b/numpy-2.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d731a1c6116ba289c1e9ee714b08a8ff882944d4ad631fd411106a30f083c326", size = 14400722, upload-time = "2024-08-26T20:06:39.16Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/22/ad/77e921b9f256d5da36424ffb711ae79ca3f451ff8489eeca544d0701d74a/numpy-2.0.2-cp310-cp310-win32.whl", hash = "sha256:984d96121c9f9616cd33fbd0618b7f08e0cfc9600a7ee1d6fd9b239186d19d97", size = 6472170, upload-time = "2024-08-26T20:06:50.361Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/10/05/3442317535028bc29cf0c0dd4c191a4481e8376e9f0db6bcf29703cadae6/numpy-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:c7b0be4ef08607dd04da4092faee0b86607f111d5ae68036f16cc787e250a131", size = 15905558, upload-time = "2024-08-26T20:07:13.881Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8b/cf/034500fb83041aa0286e0fb16e7c76e5c8b67c0711bb6e9e9737a717d5fe/numpy-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:49ca4decb342d66018b01932139c0961a8f9ddc7589611158cb3c27cbcf76448", size = 21169137, upload-time = "2024-08-26T20:07:45.345Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4a/d9/32de45561811a4b87fbdee23b5797394e3d1504b4a7cf40c10199848893e/numpy-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:11a76c372d1d37437857280aa142086476136a8c0f373b2e648ab2c8f18fb195", size = 13703552, upload-time = "2024-08-26T20:08:06.666Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c1/ca/2f384720020c7b244d22508cb7ab23d95f179fcfff33c31a6eeba8d6c512/numpy-2.0.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:807ec44583fd708a21d4a11d94aedf2f4f3c3719035c76a2bbe1fe8e217bdc57", size = 5298957, upload-time = "2024-08-26T20:08:15.83Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/0e/78/a3e4f9fb6aa4e6fdca0c5428e8ba039408514388cf62d89651aade838269/numpy-2.0.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8cafab480740e22f8d833acefed5cc87ce276f4ece12fdaa2e8903db2f82897a", size = 6905573, upload-time = "2024-08-26T20:08:27.185Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a0/72/cfc3a1beb2caf4efc9d0b38a15fe34025230da27e1c08cc2eb9bfb1c7231/numpy-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a15f476a45e6e5a3a79d8a14e62161d27ad897381fecfa4a09ed5322f2085669", size = 13914330, upload-time = "2024-08-26T20:08:48.058Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/a8/c17acf65a931ce551fee11b72e8de63bf7e8a6f0e21add4c937c83563538/numpy-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13e689d772146140a252c3a28501da66dfecd77490b498b168b501835041f951", size = 19534895, upload-time = "2024-08-26T20:09:16.536Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ba/86/8767f3d54f6ae0165749f84648da9dcc8cd78ab65d415494962c86fac80f/numpy-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9ea91dfb7c3d1c56a0e55657c0afb38cf1eeae4544c208dc465c3c9f3a7c09f9", size = 19937253, upload-time = "2024-08-26T20:09:46.263Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/df/87/f76450e6e1c14e5bb1eae6836478b1028e096fd02e85c1c37674606ab752/numpy-2.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c1c9307701fec8f3f7a1e6711f9089c06e6284b3afbbcd259f7791282d660a15", size = 14414074, upload-time = "2024-08-26T20:10:08.483Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5c/ca/0f0f328e1e59f73754f06e1adfb909de43726d4f24c6a3f8805f34f2b0fa/numpy-2.0.2-cp311-cp311-win32.whl", hash = "sha256:a392a68bd329eafac5817e5aefeb39038c48b671afd242710b451e76090e81f4", size = 6470640, upload-time = "2024-08-26T20:10:19.732Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/eb/57/3a3f14d3a759dcf9bf6e9eda905794726b758819df4663f217d658a58695/numpy-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:286cd40ce2b7d652a6f22efdfc6d1edf879440e53e76a75955bc0c826c7e64dc", size = 15910230, upload-time = "2024-08-26T20:10:43.413Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/45/40/2e117be60ec50d98fa08c2f8c48e09b3edea93cfcabd5a9ff6925d54b1c2/numpy-2.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:df55d490dea7934f330006d0f81e8551ba6010a5bf035a249ef61a94f21c500b", size = 20895803, upload-time = "2024-08-26T20:11:13.916Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/46/92/1b8b8dee833f53cef3e0a3f69b2374467789e0bb7399689582314df02651/numpy-2.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8df823f570d9adf0978347d1f926b2a867d5608f434a7cff7f7908c6570dcf5e", size = 13471835, upload-time = "2024-08-26T20:11:34.779Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7f/19/e2793bde475f1edaea6945be141aef6c8b4c669b90c90a300a8954d08f0a/numpy-2.0.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9a92ae5c14811e390f3767053ff54eaee3bf84576d99a2456391401323f4ec2c", size = 5038499, upload-time = "2024-08-26T20:11:43.902Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e3/ff/ddf6dac2ff0dd50a7327bcdba45cb0264d0e96bb44d33324853f781a8f3c/numpy-2.0.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:a842d573724391493a97a62ebbb8e731f8a5dcc5d285dfc99141ca15a3302d0c", size = 6633497, upload-time = "2024-08-26T20:11:55.09Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/72/21/67f36eac8e2d2cd652a2e69595a54128297cdcb1ff3931cfc87838874bd4/numpy-2.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05e238064fc0610c840d1cf6a13bf63d7e391717d247f1bf0318172e759e692", size = 13621158, upload-time = "2024-08-26T20:12:14.95Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/39/68/e9f1126d757653496dbc096cb429014347a36b228f5a991dae2c6b6cfd40/numpy-2.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0123ffdaa88fa4ab64835dcbde75dcdf89c453c922f18dced6e27c90d1d0ec5a", size = 19236173, upload-time = "2024-08-26T20:12:44.049Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/e9/1f5333281e4ebf483ba1c888b1d61ba7e78d7e910fdd8e6499667041cc35/numpy-2.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:96a55f64139912d61de9137f11bf39a55ec8faec288c75a54f93dfd39f7eb40c", size = 19634174, upload-time = "2024-08-26T20:13:13.634Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/71/af/a469674070c8d8408384e3012e064299f7a2de540738a8e414dcfd639996/numpy-2.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec9852fb39354b5a45a80bdab5ac02dd02b15f44b3804e9f00c556bf24b4bded", size = 14099701, upload-time = "2024-08-26T20:13:34.851Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d0/3d/08ea9f239d0e0e939b6ca52ad403c84a2bce1bde301a8eb4888c1c1543f1/numpy-2.0.2-cp312-cp312-win32.whl", hash = "sha256:671bec6496f83202ed2d3c8fdc486a8fc86942f2e69ff0e986140339a63bcbe5", size = 6174313, upload-time = "2024-08-26T20:13:45.653Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/b5/4ac39baebf1fdb2e72585c8352c56d063b6126be9fc95bd2bb5ef5770c20/numpy-2.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:cfd41e13fdc257aa5778496b8caa5e856dc4896d4ccf01841daee1d96465467a", size = 15606179, upload-time = "2024-08-26T20:14:08.786Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/43/c1/41c8f6df3162b0c6ffd4437d729115704bd43363de0090c7f913cfbc2d89/numpy-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9059e10581ce4093f735ed23f3b9d283b9d517ff46009ddd485f1747eb22653c", size = 21169942, upload-time = "2024-08-26T20:14:40.108Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/39/bc/fd298f308dcd232b56a4031fd6ddf11c43f9917fbc937e53762f7b5a3bb1/numpy-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:423e89b23490805d2a5a96fe40ec507407b8ee786d66f7328be214f9679df6dd", size = 13711512, upload-time = "2024-08-26T20:15:00.985Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/96/ff/06d1aa3eeb1c614eda245c1ba4fb88c483bee6520d361641331872ac4b82/numpy-2.0.2-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:2b2955fa6f11907cf7a70dab0d0755159bca87755e831e47932367fc8f2f2d0b", size = 5306976, upload-time = "2024-08-26T20:15:10.876Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2d/98/121996dcfb10a6087a05e54453e28e58694a7db62c5a5a29cee14c6e047b/numpy-2.0.2-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:97032a27bd9d8988b9a97a8c4d2c9f2c15a81f61e2f21404d7e8ef00cb5be729", size = 6906494, upload-time = "2024-08-26T20:15:22.055Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/15/31/9dffc70da6b9bbf7968f6551967fc21156207366272c2a40b4ed6008dc9b/numpy-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e795a8be3ddbac43274f18588329c72939870a16cae810c2b73461c40718ab1", size = 13912596, upload-time = "2024-08-26T20:15:42.452Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b9/14/78635daab4b07c0930c919d451b8bf8c164774e6a3413aed04a6d95758ce/numpy-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b258c385842546006213344c50655ff1555a9338e2e5e02a0756dc3e803dd", size = 19526099, upload-time = "2024-08-26T20:16:11.048Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/26/4c/0eeca4614003077f68bfe7aac8b7496f04221865b3a5e7cb230c9d055afd/numpy-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fec9451a7789926bcf7c2b8d187292c9f93ea30284802a0ab3f5be8ab36865d", size = 19932823, upload-time = "2024-08-26T20:16:40.171Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f1/46/ea25b98b13dccaebddf1a803f8c748680d972e00507cd9bc6dcdb5aa2ac1/numpy-2.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9189427407d88ff25ecf8f12469d4d39d35bee1db5d39fc5c168c6f088a6956d", size = 14404424, upload-time = "2024-08-26T20:17:02.604Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c8/a6/177dd88d95ecf07e722d21008b1b40e681a929eb9e329684d449c36586b2/numpy-2.0.2-cp39-cp39-win32.whl", hash = "sha256:905d16e0c60200656500c95b6b8dca5d109e23cb24abc701d41c02d74c6b3afa", size = 6476809, upload-time = "2024-08-26T20:17:13.553Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ea/2b/7fc9f4e7ae5b507c1a3a21f0f15ed03e794c1242ea8a242ac158beb56034/numpy-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:a3f4ab0caa7f053f6797fcd4e1e25caee367db3112ef2b6ef82d749530768c73", size = 15911314, upload-time = "2024-08-26T20:17:36.72Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8f/3b/df5a870ac6a3be3a86856ce195ef42eec7ae50d2a202be1f5a4b3b340e14/numpy-2.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7f0a0c6f12e07fa94133c8a67404322845220c06a9e80e85999afe727f7438b8", size = 21025288, upload-time = "2024-08-26T20:18:07.732Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/2c/97/51af92f18d6f6f2d9ad8b482a99fb74e142d71372da5d834b3a2747a446e/numpy-2.0.2-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:312950fdd060354350ed123c0e25a71327d3711584beaef30cdaa93320c392d4", size = 6762793, upload-time = "2024-08-26T20:18:19.125Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/46/de1fbd0c1b5ccaa7f9a005b66761533e2f6a3e560096682683a223631fe9/numpy-2.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26df23238872200f63518dd2aa984cfca675d82469535dc7162dc2ee52d9dd5c", size = 19334885, upload-time = "2024-08-26T20:18:47.237Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cc/dc/d330a6faefd92b446ec0f0dfea4c3207bb1fef3c4771d19cf4543efd2c78/numpy-2.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a46288ec55ebbd58947d31d72be2c63cbf839f0a63b49cb755022310792a3385", size = 15828784, upload-time = "2024-08-26T20:19:11.19Z" }, +] + +[[package]] +name = "numpy" +version = "2.2.6" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +resolution-markers = [ + "python_full_version >= '3.10'", +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9a/3e/ed6db5be21ce87955c0cbd3009f2803f59fa08df21b5df06862e2d8e2bdd/numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb", size = 21165245, upload-time = "2025-05-17T21:27:58.555Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/22/c2/4b9221495b2a132cc9d2eb862e21d42a009f5a60e45fc44b00118c174bff/numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90", size = 14360048, upload-time = "2025-05-17T21:28:21.406Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/fd/77/dc2fcfc66943c6410e2bf598062f5959372735ffda175b39906d54f02349/numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163", size = 5340542, upload-time = "2025-05-17T21:28:30.931Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/7a/4f/1cb5fdc353a5f5cc7feb692db9b8ec2c3d6405453f982435efc52561df58/numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf", size = 6878301, upload-time = "2025-05-17T21:28:41.613Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/eb/17/96a3acd228cec142fcb8723bd3cc39c2a474f7dcf0a5d16731980bcafa95/numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83", size = 14297320, upload-time = "2025-05-17T21:29:02.78Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b4/63/3de6a34ad7ad6646ac7d2f55ebc6ad439dbbf9c4370017c50cf403fb19b5/numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915", size = 16801050, upload-time = "2025-05-17T21:29:27.675Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/07/b6/89d837eddef52b3d0cec5c6ba0456c1bf1b9ef6a6672fc2b7873c3ec4e2e/numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680", size = 15807034, upload-time = "2025-05-17T21:29:51.102Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/01/c8/dc6ae86e3c61cfec1f178e5c9f7858584049b6093f843bca541f94120920/numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289", size = 18614185, upload-time = "2025-05-17T21:30:18.703Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/5b/c5/0064b1b7e7c89137b471ccec1fd2282fceaae0ab3a9550f2568782d80357/numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d", size = 6527149, upload-time = "2025-05-17T21:30:29.788Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a3/dd/4b822569d6b96c39d1215dbae0582fd99954dcbcf0c1a13c61783feaca3f/numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3", size = 12904620, upload-time = "2025-05-17T21:30:48.994Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload-time = "2025-05-17T21:31:19.36Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload-time = "2025-05-17T21:31:41.087Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload-time = "2025-05-17T21:31:50.072Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload-time = "2025-05-17T21:32:01.712Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload-time = "2025-05-17T21:32:23.332Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload-time = "2025-05-17T21:32:47.991Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload-time = "2025-05-17T21:33:11.728Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload-time = "2025-05-17T21:33:39.139Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload-time = "2025-05-17T21:33:50.273Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload-time = "2025-05-17T21:34:09.135Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload-time = "2025-05-17T21:34:39.648Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload-time = "2025-05-17T21:35:01.241Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload-time = "2025-05-17T21:35:10.622Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload-time = "2025-05-17T21:35:21.414Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload-time = "2025-05-17T21:35:42.174Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload-time = "2025-05-17T21:36:06.711Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload-time = "2025-05-17T21:36:29.965Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload-time = "2025-05-17T21:36:56.883Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload-time = "2025-05-17T21:37:07.368Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload-time = "2025-05-17T21:37:26.213Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload-time = "2025-05-17T21:37:56.699Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload-time = "2025-05-17T21:38:18.291Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload-time = "2025-05-17T21:38:27.319Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload-time = "2025-05-17T21:38:38.141Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload-time = "2025-05-17T21:38:58.433Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload-time = "2025-05-17T21:39:22.638Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload-time = "2025-05-17T21:39:45.865Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload-time = "2025-05-17T21:40:13.331Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload-time = "2025-05-17T21:43:46.099Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload-time = "2025-05-17T21:44:05.145Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload-time = "2025-05-17T21:40:44Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload-time = "2025-05-17T21:41:05.695Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload-time = "2025-05-17T21:41:15.903Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload-time = "2025-05-17T21:41:27.321Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload-time = "2025-05-17T21:41:49.738Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload-time = "2025-05-17T21:42:14.046Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload-time = "2025-05-17T21:42:37.464Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload-time = "2025-05-17T21:43:05.189Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload-time = "2025-05-17T21:43:16.254Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload-time = "2025-05-17T21:43:35.479Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/9e/3b/d94a75f4dbf1ef5d321523ecac21ef23a3cd2ac8b78ae2aac40873590229/numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d", size = 21040391, upload-time = "2025-05-17T21:44:35.948Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/17/f4/09b2fa1b58f0fb4f7c7963a1649c64c4d315752240377ed74d9cd878f7b5/numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db", size = 6786754, upload-time = "2025-05-17T21:44:47.446Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/af/30/feba75f143bdc868a1cc3f44ccfa6c4b9ec522b36458e738cd00f67b573f/numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543", size = 16643476, upload-time = "2025-05-17T21:45:11.871Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/37/48/ac2a9584402fb6c0cd5b5d1a91dcf176b15760130dd386bbafdbfe3640bf/numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00", size = 12812666, upload-time = "2025-05-17T21:45:31.426Z" }, +] + +[[package]] +name = "opencv-python-headless" +version = "4.12.0.88" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +dependencies = [ + { name = "numpy", version = "1.24.4", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version < '3.9'" }, + { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version == '3.9.*'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version >= '3.10'" }, +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a4/63/6861102ec149c3cd298f4d1ea7ce9d6adbc7529221606ff1dab991a19adb/opencv-python-headless-4.12.0.88.tar.gz", hash = "sha256:cfdc017ddf2e59b6c2f53bc12d74b6b0be7ded4ec59083ea70763921af2b6c09", size = 95379675, upload-time = "2025-07-07T09:21:06.815Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f7/7d/414e243c5c8216a5277afd104a319cc1291c5e23f5eeef512db5629ee7f4/opencv_python_headless-4.12.0.88-cp37-abi3-macosx_13_0_arm64.whl", hash = "sha256:1e58d664809b3350c1123484dd441e1667cd7bed3086db1b9ea1b6f6cb20b50e", size = 37877864, upload-time = "2025-07-07T09:14:41.693Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/05/14/7e162714beed1cd5e7b5eb66fcbcba2f065c51b1d9da2463024c84d2f7c0/opencv_python_headless-4.12.0.88-cp37-abi3-macosx_13_0_x86_64.whl", hash = "sha256:365bb2e486b50feffc2d07a405b953a8f3e8eaa63865bc650034e5c71e7a5154", size = 57326608, upload-time = "2025-07-07T09:14:51.885Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/69/4e/116720df7f1f7f3b59abc608ca30fbec9d2b3ae810afe4e4d26483d9dfa0/opencv_python_headless-4.12.0.88-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:aeb4b13ecb8b4a0beb2668ea07928160ea7c2cd2d9b5ef571bbee6bafe9cc8d0", size = 33145800, upload-time = "2025-07-07T09:15:00.367Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/89/53/e19c21e0c4eb1275c3e2c97b081103b6dfb3938172264d283a519bf728b9/opencv_python_headless-4.12.0.88-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:236c8df54a90f4d02076e6f9c1cc763d794542e886c576a6fee46ec8ff75a7a9", size = 54023419, upload-time = "2025-07-07T09:15:10.164Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/bf/9c/a76fd5414de6ec9f21f763a600058a0c3e290053cea87e0275692b1375c0/opencv_python_headless-4.12.0.88-cp37-abi3-win32.whl", hash = "sha256:fde2cf5c51e4def5f2132d78e0c08f9c14783cd67356922182c6845b9af87dbd", size = 30225230, upload-time = "2025-07-07T09:15:17.045Z" }, + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f2/35/0858e9e71b36948eafbc5e835874b63e515179dc3b742cbe3d76bc683439/opencv_python_headless-4.12.0.88-cp37-abi3-win_amd64.whl", hash = "sha256:86b413bdd6c6bf497832e346cd5371995de148e579b9774f8eba686dee3f5528", size = 38923559, upload-time = "2025-07-07T09:15:25.229Z" }, +] + +[[package]] +name = "pip" +version = "25.0.1" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +resolution-markers = [ + "python_full_version < '3.9'", +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/70/53/b309b4a497b09655cb7e07088966881a57d082f48ac3cb54ea729fd2c6cf/pip-25.0.1.tar.gz", hash = "sha256:88f96547ea48b940a3a385494e181e29fb8637898f88d88737c5049780f196ea", size = 1950850, upload-time = "2025-02-09T17:14:04.423Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/c9/bc/b7db44f5f39f9d0494071bddae6880eb645970366d0a200022a1a93d57f5/pip-25.0.1-py3-none-any.whl", hash = "sha256:c46efd13b6aa8279f33f2864459c8ce587ea6a1a59ee20de055868d8f7688f7f", size = 1841526, upload-time = "2025-02-09T17:14:01.463Z" }, +] + +[[package]] +name = "pip" +version = "25.2" +source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" } +resolution-markers = [ + "python_full_version >= '3.10'", + "python_full_version == '3.9.*'", +] +sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/20/16/650289cd3f43d5a2fadfd98c68bd1e1e7f2550a1a5326768cddfbcedb2c5/pip-25.2.tar.gz", hash = "sha256:578283f006390f85bb6282dffb876454593d637f5d1be494b5202ce4877e71f2", size = 1840021, upload-time = "2025-07-30T21:50:15.401Z" } +wheels = [ + { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b7/3f/945ef7ab14dc4f9d7f40288d2df998d1837ee0888ec3659c813487572faa/pip-25.2-py3-none-any.whl", hash = "sha256:6d67a2b4e7f14d8b31b8b52648866fa717f45a1eb70e83002f4331d07e953717", size = 1752557, upload-time = "2025-07-30T21:50:13.323Z" }, +] + +[[package]] +name = "sophon-ai-project" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "numpy", version = "1.24.4", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version < '3.9'" }, + { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version == '3.9.*'" }, + { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "opencv-python-headless" }, +] + +[package.dev-dependencies] +dev = [ + { name = "dfss" }, + { name = "pip", version = "25.0.1", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version < '3.9'" }, + { name = "pip", version = "25.2", source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }, marker = "python_full_version >= '3.9'" }, +] + +[package.metadata] +requires-dist = [ + { name = "numpy", specifier = ">=1.24.4" }, + { name = "opencv-python-headless", specifier = ">=4.12.0.88" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "dfss", specifier = ">=1.10.4" }, + { name = "pip", specifier = ">=25.0.1" }, +]