【目标跟踪】光流跟踪(python、c++代码)

文章目录

    • 前言
    • 一、代码流程与思路
    • 二、python 代码
      • 2.1 代码详解
      • 2.2 完整代码
    • 三、c++ 代码
    • 四、结果展示

前言

  1. 流利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存在的对应关系,从而计算出相邻帧之间物体的运动信息的一种方法。
  2. 本文主要展示代码以及代码解释,对于相对应的原理,以后有机会再写(下次一定)。
  3. 本文所用数据源于网上开源数据。找不到数据的小伙伴可以私我拿数据。
  4. 文章提供 python、c++ 代码。python 代码可以直接跑通。c++ 代码集成一个 class ,可以在自己工程中使用。
  5. 效果图:
    在这里插入图片描述

一、代码流程与思路

  1. 输入:上一帧图片、preImage 上一帧图片检测框、image 当前帧图片。 输出:当前帧光流预测框
  2. 特征点提取。对上一帧图片 preImage 提取目标框里的特征点,这里采取的是 fast 角点检测。
  3. preImage、image 光流跟踪、在 image 中找出对应的特征点。
  4. 由特征点对应关系可以得出当前帧的目标框。

二、python 代码

2.1 代码详解

(1) fast 角点检测

fast = cv2.FastFeatureDetector_create(threshold=9, nonmaxSuppression=True, type=cv2.FastFeatureDetector_TYPE_9_16)
  1. threshold:边缘轨迹点和中心点的差值阈值。
  2. nonmaxSuppression:是否进行非极大值抑制
  3. type:提供轨迹范围。我们这里是从圆周轨迹16个点,当9个满足条件,此判定圆心像素点为特征点

我们这里只对检测框里的像素做特征点检测

def SelectPointByBox(img, det):top_x, top_y, bottom_x, bottom_y = [int(_) for _ in det[:4]]cutimg = img[max(0, top_y - 2):min(bottom_y + 2, 1080), max(0, top_x - 2):min(1920, bottom_x + 2)]fast = cv2.FastFeatureDetector_create(threshold=9, nonmaxSuppression=True, type=cv2.FastFeatureDetector_TYPE_9_16)kps = fast.detect(cutimg, 10)  # Ip-t < Ip < Ip+tkp = []for p in kps:t = []t.append(np.float32(p.pt[0] + top_x))t.append(np.float32(p.pt[1] + top_y))kp.append(np.array(t).reshape(1, 2))return np.array(kp)

(2) 追踪稀疏特征点

cv2.calcOpticalFlowPyrLK(preImgGray, gray, prePt, pt, **lkParms)
  1. preImgGray:前一帧图片灰度图。
  2. gray:当前帧图片灰度图
  3. prePt:前一帧图片的特征点
  4. pt:None
lkParms = dict(winSize=(15, 15), maxLevel=2, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
  1. winSize: 每个金字塔级别上搜索窗口的大小
  2. maxLevel: 最大金字塔层数
  3. criteria:指定迭代搜索算法的终止条件,在指定的最大迭代次数 10 之后或搜索窗口移动小于 0.03
def OpticalFlowLk(preImg, curImg, prePt, pt):lkParms = dict(winSize=(15, 15), maxLevel=2, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))gray = cv2.cvtColor(curImg, cv2.COLOR_BGR2GRAY)preImgGray = cv2.cvtColor(preImg, cv2.COLOR_BGR2GRAY)# nextPts:前一帧图像的特征点跟踪后的点  st:特征点是否找到,找到状态为1,否则为0  err:每个特征点的误差,即前一帧和当前帧中特征点的位置差异nextPts, st, err = cv2.calcOpticalFlowPyrLK(preImgGray, gray, prePt, pt, **lkParms)# print("p1", nextPts, "st", st, "err", err)goodNewPt = nextPts[st == 1]  # 光流跟踪后特征点goodOldPt = prePt[st == 1]  # 上一帧特征点return goodOldPt, goodNewPt

(3) 预测当前帧目标检测框

  1. 现在我们获取到了 prePt curPt pre_detect_box
  2. 由像素对应关系,我们可以求出 cur_detect_box
def CalculateShift(prePt, curPt):x = curPt[:, 0] - prePt[:, 0]y = curPt[:, 1] - prePt[:, 1]avgX = np.mean(x)avgY = np.mean(y)return avgX, avgYdef get_box(ditection, prePt, curPt):d_x, d_y = CalculateShift(prePt, curPt)  # 计算偏移量box = [0] * 4box[0], box[2], box[1], box[3] = ditection[0] + d_x, ditection[2] + d_x, ditection[1] + d_y, ditection[3] + d_yreturn box

2.2 完整代码

代码可直接跑通

import cv2
import os
import numpy as npdef GetImg(path, num):fn = os.path.join(path, 'img', '%06d.jpg' % (num))im = cv2.imread(fn)return imdef GetDetFrameRes(seq_dets, frame):detects = seq_dets[seq_dets[:, 0] == frame, 2:7]detects[:, 2:4] += detects[:, 0:2]  # convert to [x1,y1,w,h] to [x1,y1,x2,y2]return detectsdef SelectPointByBox(img, det):top_x, top_y, bottom_x, bottom_y = [int(_) for _ in det[:4]]cutimg = img[max(0, top_y - 2):min(bottom_y + 2, 1080), max(0, top_x - 2):min(1920, bottom_x + 2)]fast = cv2.FastFeatureDetector_create(threshold=9, nonmaxSuppression=True, type=cv2.FastFeatureDetector_TYPE_9_16)kps = fast.detect(cutimg, 10)  # Ip-t < Ip < Ip+tkp = []for p in kps:t = []t.append(np.float32(p.pt[0] + top_x))t.append(np.float32(p.pt[1] + top_y))kp.append(np.array(t).reshape(1, 2))return np.array(kp)def OpticalFlowLk(preImg, curImg, prePt, pt):lkParms = dict(winSize=(15, 15), maxLevel=2, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))gray = cv2.cvtColor(curImg, cv2.COLOR_BGR2GRAY)preImgGray = cv2.cvtColor(preImg, cv2.COLOR_BGR2GRAY)# nextPts:前一帧图像的特征点跟踪后的点    st:特征点是否找到,找到状态为1,否则为0     err:每个特征点的误差,即前一帧和当前帧中特征点的位置差异nextPts, st, err = cv2.calcOpticalFlowPyrLK(preImgGray, gray, prePt, pt, **lkParms)# print("p1", nextPts, "st", st, "err", err)goodNewPt = nextPts[st == 1]  # 光流跟踪后特征点goodOldPt = prePt[st == 1]  # 上一帧特征点return goodOldPt, goodNewPtdef CalculateShift(prePt, curPt):x = curPt[:, 0] - prePt[:, 0]y = curPt[:, 1] - prePt[:, 1]avgX = np.mean(x)avgY = np.mean(y)return avgX, avgYdef get_box(ditection, prePt, curPt):d_x, d_y = CalculateShift(prePt, curPt)  # 计算偏移量box = [0] * 4box[0], box[2], box[1], box[3] = ditection[0] + d_x, ditection[2] + d_x, ditection[1] + d_y, ditection[3] + d_yreturn boxdef Test():pathroot = ".\\"resPath = pathroot + "det.txt"video_path = pathroot + "video.mp4"video = cv2.VideoWriter(video_path, cv2.VideoWriter_fourcc('m', 'p', '4', 'v'), 10, (1920, 1080))detRes = np.loadtxt(resPath, delimiter=',')preImg = GetImg(pathroot, 1)  # 初始化为000001.jpg   preImg:上一帧图片for num in range(2, int(max(detRes[:, 0]))):print(num)img = GetImg(pathroot, num)  # img:当前帧图片dets = GetDetFrameRes(detRes, num - 1)  # 上一帧图片的检测框drawImg = img.copy()for i in range(len(dets)):detect = dets[i]  # 上一帧图片的单个框boxKeyPt = SelectPointByBox(preImg, detect)  # 找在框里的关键点if (len(boxKeyPt) < 3):continue  # 框里关键点少于3 不做跟踪prePt, curPt = OpticalFlowLk(preImg, img, boxKeyPt, None)bbox = get_box(detect, prePt, curPt)if np.isnan(bbox[0]): continuefor i in range(curPt.shape[0] - 1, -1, -1):c, d = curPt[i].ravel()if not (max(0, bbox[0] - 2) <= c <= min(1920, bbox[2] + 2) andmax(0, bbox[1] - 2) <= d <= min(1080, bbox[3] + 2)):prePt = np.delete(prePt, i, 0)curPt = np.delete(curPt, i, 0)new_b = get_box(detect, prePt, curPt)  # 最终框if np.isnan(new_b[0]): continuecv2.rectangle(drawImg, (int(new_b[0]), int(new_b[1])), (int(new_b[2]), int(new_b[3])), (96, 48, 176), 2)mask = np.zeros_like(preImg)color = np.random.randint(0, 255, (20000, 3))for i, (new, old) in enumerate(zip(prePt, curPt)):a, b = new.ravel()c, d = old.ravel()mask = cv2.line(mask, (int(a), int(b)), (int(c), int(d)), color[i].tolist(), 2)drawImg = cv2.circle(drawImg, (int(a), int(b)), 1, color[i].tolist(), -1)drawImg = cv2.add(drawImg, mask)cv2.imshow("img", drawImg)cv2.waitKey(10)preImg = img.copy()video.write(drawImg)video.release()if __name__ == "__main__":Test()

三、c++ 代码

  1. Optical(std::vector<cv::Rect_> boxes, cv::Mat preImg, cv::Mat curImg) 构造函数
  2. void OpticalDeal(); 处理计算
  3. std::vector<cv::Rect_> GetBoxResult(); 获取结果

Optical.h 文件

#include <vector>
#include "opencv2/opencv.hpp"
#include "opencv2/features2d.hpp"class Optical
{
public:Optical(std::vector<cv::Rect_<float>> boxes, cv::Mat preImg, cv::Mat curImg){mBoxes = boxes;mCurImg = curImg;mPreImg = preImg;}   void OpticalDeal();                                     // 计算std::vector<cv::Rect_<float>> GetBoxResult();           // 获取光流跟踪后得到的结果框 private:std::vector<cv::Point2f> GetCornorPoint();              // fast检测关键点坐标cv::Rect_<float> GetExpBox(cv::Rect_<float> box);       // 获取比检测框大pixeParam像素的框void OpticalFlowLk(std::vector<cv::Point2f> prePt);     // 光流跟踪cv::Rect_<float> GetUpdateBox(cv::Rect_<float> box, std::vector<cv::Point2f> prePoints, std::vector<cv::Point2f> curPoints);    // 修正框void SelectPt(cv::Rect_<float> box, std::vector<cv::Point2f> &prePoints, std::vector<cv::Point2f> &curPoints);                  // 选取合适的关键点 过滤一部分关键点cv::Rect_<float> CorrectBox(cv::Rect_<float> box); private:int pixeParam = 2;                      // 关键点选取像素参数 多截取pixeParam像素int fastFeatureDetectParam = 10;        // fast关键点检测参数,参数越小,关键点检测越多int keyPointCountParam = 3;             // 检测框里关键点较少就不进行光流跟踪std::vector<int> mIndex = {0};          // 光流跟踪每个框关键点的索引位置 std::vector<cv::Rect_<float>> mBoxes;   // 检测框cv::Mat mPreImg;                        // 上一帧图cv::Mat mCurImg;                        // 当前图片
};  

Optical.cpp 文件

#include "Optical.h"std::vector<cv::Rect_<float>> Optical::GetBoxResult()
{return mBoxes;
}void Optical::OpticalDeal()
{std::vector<cv::Point2f> fastKeyPoint = GetCornorPoint();   // fast检测的角点OpticalFlowLk(fastKeyPoint);                                // 光流跟踪 获取点与点匹配
}std::vector<cv::Point2f> Optical::GetCornorPoint()
{   std::vector<cv::Point2f> res;cv::Ptr<cv::FastFeatureDetector> detector = cv::FastFeatureDetector::create(fastFeatureDetectParam);int num = 0;                                            // 计数多少个关键点 for (int i = 0; i < mBoxes.size(); ++i) {std::vector<cv::KeyPoint> keyPoints;cv::Rect_<float> newBox = GetExpBox(mBoxes[i]);cv::Mat image = mPreImg(newBox);                    // 截取检测框检测的图片detector->detect(image, keyPoints);num = num + keyPoints.size();mIndex.push_back(num);for (auto points:keyPoints) {points.pt = points.pt + cv::Point_<float>(newBox.x, newBox.y);res.push_back(points.pt);}}return res;
}void Optical::OpticalFlowLk(std::vector<cv::Point2f> prePt)
{cv::Mat curImgGray, preImgGray;std::vector<uchar> status;std::vector<float> err;cv::cvtColor(mCurImg, curImgGray, cv::COLOR_RGBA2GRAY);     // 当前图片灰度cv::cvtColor(mPreImg, preImgGray, cv::COLOR_RGBA2GRAY);     // 上一帧图片灰度std::vector<cv::Point2f> pt;cv::calcOpticalFlowPyrLK(preImgGray, curImgGray, prePt, pt, status, err); for (int i = 0; i < mIndex.size() - 1; ++i) {int leftIndex = mIndex[i], rightIndex = mIndex[i + 1];// 关键点太少不进行光流跟踪(1)if (rightIndex - leftIndex >= keyPointCountParam) {std::vector<cv::Point2f> preIndexPt(prePt.begin() + leftIndex, prePt.begin() + rightIndex);std::vector<cv::Point2f> indexPt(pt.begin() + leftIndex, pt.begin()+rightIndex);std::vector<uchar> indexStatus(status.begin() + leftIndex, status.begin()+rightIndex);int length = preIndexPt.size(); for (int j = length - 1 ; j > -1; --j) {if (status[j] != 1) {indexPt.erase(indexPt.begin() + i);preIndexPt.erase(preIndexPt.begin() + j);}}// 跟踪到的关键点少不进行光流跟踪(2)if (preIndexPt.size() > keyPointCountParam) {cv::Rect_<float> newBox = GetUpdateBox(mBoxes[i], preIndexPt, indexPt);SelectPt(newBox, preIndexPt, indexPt);if (preIndexPt.size() > keyPointCountParam) {mBoxes[i] = GetUpdateBox(mBoxes[i], preIndexPt, indexPt);}}}}
}// expend pixeParam bounding box to optical track
cv::Rect_<float> Optical::GetExpBox(cv::Rect_<float> box) 
{cv::Rect_<float> newBox = box + cv::Point_<float>(-pixeParam, -pixeParam) + cv::Size_<float>(2 * pixeParam, 2 * pixeParam);return CorrectBox(newBox);
}cv::Rect_<float> Optical::GetUpdateBox(cv::Rect_<float> box, std::vector<cv::Point2f> prePoints, std::vector<cv::Point2f> curPoints)
{float avgX = 0, avgY = 0;int length = prePoints.size();for (int i = 0; i < length; ++i) {avgX += curPoints[i].x - prePoints[i].x;avgY += curPoints[i].y - prePoints[i].y;}avgX = avgX / length;avgY = avgY / length;cv::Rect_<float> resBox = box + cv::Point_<float>(avgX, avgY);return CorrectBox(resBox);
}void Optical::SelectPt(cv::Rect_<float> box, std::vector<cv::Point2f> &prePoints, std::vector<cv::Point2f> &curPoints)
{int length = prePoints.size();for (int i = length - 1 ; i >= 0; --i) {float x = curPoints[i].x, y = curPoints[i].y;if (x < (box.x - pixeParam) || x > (box.x + box.width + pixeParam) || y < (box.y - pixeParam) || y > (box.y + box.height + pixeParam)) {curPoints.erase(curPoints.begin() + i);prePoints.erase(prePoints.begin() + i);}}
}// correct box when box beyond border
cv::Rect_<float> Optical::CorrectBox(cv::Rect_<float> box)
{int w = mPreImg.cols, h = mPreImg.rows;box.x = (box.x <= 0) ? 0 : box.x;box.y = (box.y <= 0) ? 0 : box.y;box.width = ((box.width + box.x) >= w - 1) ? w - box.x - 1 : box.width;box.height = ((box.height + box.y) >= h - 1) ? h - box.y - 1 : box.height;return box;
}

四、结果展示

在这里插入图片描述

由于上传限制,只上传 gif 压缩结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/204926.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Maven 介绍

文章目录 什么是 maven为什么要选择mavenmaven 仓库什么是maven中央仓库什么是maven本地仓库 idea如何创建出maven项目如何引入第三方库依赖配置国内源 下载 Maven Helper 插件查看各个项目之间的依赖关系 什么是 maven Maven是 Apache 下的一个纯 Java 开发的开源项目&#x…

opencv-直方图

直方图是一种对图像亮度分布的统计表示&#xff0c;它显示了图像中每个灰度级别的像素数量。在OpenCV中&#xff0c;你可以使用cv2.calcHist() 函数计算直方图。 以下是一个简单的示例&#xff0c;演示如何计算和绘制图像的直方图&#xff1a; import cv2 import numpy as np …

超声波眼镜清洗机都有哪些是比较值得入手的?眼镜清洗机推荐

在当今社会&#xff0c;眼镜已经成为了我们日常生活中不可或缺的一部分。然而&#xff0c;眼镜的清洗问题却一直困扰着许多人。眼镜上的污垢和油脂不仅影响其美观&#xff0c;更重要的是可能会对眼睛的健康产生不良影响。因此&#xff0c;我们需要一种高效的眼镜清洗机来帮助我…

无需部署服务器,如何结合内网穿透实现公网访问导航页工具Dashy

文章目录 简介1. 安装Dashy2. 安装cpolar3.配置公网访问地址4. 固定域名访问 简介 Dashy 是一个开源的自托管的导航页配置服务&#xff0c;具有易于使用的可视化编辑器、状态检查、小工具和主题等功能。你可以将自己常用的一些网站聚合起来放在一起&#xff0c;形成自己的导航…

泛型边界的问题

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 我们花了两篇文章讲述了…

上市公司-绿色专利申请、授权(2000-2022年)

一、数据介绍 数据名称&#xff1a;上市公司-绿色专利申请、授权 数据范围&#xff1a;A股上市公司 数据年份&#xff1a;2000-2022年 数据样本&#xff1a;56167条 数据来源&#xff1a;国家知识产权局、WIPO绿色专利清单 数据整理&#xff1a;自主整理 二、数据用途 数…

开发知识点-ArkTS-鸿蒙开发-Typescript

Typescript IED IED https://developer.harmonyos.com/cn/develop/deveco-studio/#download

医疗影像数据集—CT、X光、骨折、阿尔茨海默病MRI、肺部、肿瘤疾病等图像数据集

最近收集了一大波关于CT、X光等医疗方面的数据集包含骨折、阿尔茨海默病MRI、肺部疾病等类型的医疗影像数据&#xff0c;废话不多说&#xff0c;给大家逐一介绍&#xff01;&#xff01; 1、彩色预处理阿尔茨海默病MRI(磁共振成像)图像数据集 彩色预处理阿尔茨海默病MRI(磁共…

Python爬虫404错误:解决方案总结

在进行网络爬虫开发的过程中&#xff0c;经常会遇到HTTP 404错误&#xff0c;即“Not Found”错误。这种错误通常表示所请求的资源不存在。对于爬虫开发者来说&#xff0c;处理这类错误是至关重要的&#xff0c;因为它们可能会导致爬虫无法正常工作。本文将探讨Python爬虫遇到4…

如何在 Vim 中剪切、复制和粘贴

目录 前言 如何在 Vim 编辑器中复制文本 如何在 Vim 编辑器中剪切文本 如何在 Vim 编辑器中粘贴文本 如何通过选择文本来剪切和复制文本 通过选择文本复制 在 Vim 中选择文本来剪切文本 前言 在本篇 Vim 快速技巧中&#xff0c;你将学习到剪切和复制粘贴的相关知识。 剪…

2022年土地出让数据,超多字段,附数据可视化

分享一个土地出让数据&#xff0c;详细信息如下&#xff1a; 数据名称: 2022年土地出让数据 数据格式: Shp、excel 数据时间: 2022年 数据几何类型: 点 数据坐标系: WGS84坐标系 数据来源&#xff1a;网络公开数据 部分字段如下&#xff1a; 如需获取可搜“吧唧数…

Django请求生命周期流程

浏览器发起请求。 先经过网关接口&#xff0c;Django自带的是wsgiref&#xff0c;请求来的时候解析封装&#xff0c;响应走的时候打包处理&#xff0c;这个wsgiref模块本身能够支持的并发量很少&#xff0c;最多1000左右&#xff0c;上线之后会换成uwsgi&#xff0c;并且还会加…

python基于YOLOv7系列模型【yolov7-tiny/yolov7/yolov7x】开发构建钢铁产业产品智能自动化检测识别系统

在前文的项目开发实践中&#xff0c;我们已经以钢铁产业产品缺陷检测数据场景为基准&#xff0c;陆续开发构建了多款目标检测模型&#xff0c;感兴趣的话可以自行阅读即可。 《YOLOv3老矣尚能战否&#xff1f;基于YOLOv3开发构建建钢铁产业产品智能自动化检测识别系统&#xf…

Day44力扣打卡

打卡记录 给小朋友们分糖果 II&#xff08;容斥原理 隔板法&#xff09; 链接 def c2(n):return n * (n - 1) // 2 if n > 1 else 0class Solution:def distributeCandies(self, n: int, limit: int) -> int:return c2(n 2) - 3 * c2(n - limit 1) 3 * c2(n - 2 * …

tcpdump使用心得

参考原文 https://danielmiessler.com/p/tcpdump/ 几个用例 tcpdump -i eth0 显示eth0网卡当前所有的抓包情况eth0是网卡名&#xff0c;可以通过ifconfig获得&#xff0c;也可以通过 tcpdump -D 显示当前可以监听的网卡 -i 参数表示接口&#xff0c;后跟要监听的网卡 tcpdu…

初刷leetcode题目(10)——数据结构与算法

&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️Take your time ! &#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️…

Unity-链接MySql5.7

链接MySql5.7 前言&#xff1a; 为什么不选择最新的MySQL8.0或者MySQL8.2呢&#xff0c;实际发现&#xff0c;如果使用这两个版本&#xff0c;虽然能够用同样的方法找到合适的dll&#xff0c;但是在编写代码的过程中往往会卡死&#xff0c;非常的影响效率&#xff0c;因此放弃…

webGL开发虚拟实验室

开发虚拟实验室是一个具有挑战性但也非常有趣和有价值的任务。通过 WebGL&#xff0c;你可以创建交互式、沉浸式的虚拟实验室&#xff0c;使用户能够进行实验和学习。以下是一些步骤和关键考虑因素&#xff0c;帮助你开始开发虚拟实验室&#xff0c;希望对大家有所帮助。北京木…

绘制彩色正多边形-第11届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第10讲。 绘制彩色正多边形…

中兴小鲜50 ZTE 畅行50 刷机救砖演示机7543n root 虎贲 展锐 T760 解锁BL

系统信息 网络制式 支持中国移动、中国电信、中国联通、中国广电四大运营商5G频段&#xff1b;支持4G/3G/2G 系统平台 MyOS 13.0&#xff08;基于Android 13&#xff09; 硬件信息 处理器 展锐T760&#xff0c;高性能8核5G芯片 存储 6GB RAM128GB ROM 扩展 不支持 电池容…