计算机视觉项目中的文件批量操作与文件批量预处理
计算机视觉项目中的文件批量操作与文件批量预处理
目录
- 数据集制作
- 文件批量重命名
- 文件批量移动
- 将文件批量按照一定格式进行重命名
- 修改xml文件内容的方法
引言
在计算机视觉项目中,文件批量操作和文件批量预处理是必不可少的步骤。它们涉及处理大量的图像文件,包括读取、处理、保存和预处理。本文将介绍一些常见的技术和方法,以帮助您在计算机视觉项目中有效地进行文件批量操作和文件批量预处理。
1. 数据集制作
人工智能就是有多少人工产生多少智能,在计算机视觉项目中,数据集至关重要,下面是如何使用视频抽帧技术实现数据集的制作。以下代码中_videoPlay函数是实时显示导入的视频,CutVideo函数实现手动抽帧,在显示时按c键则抽取当前帧,按Esc键关闭视频。ExtractAll函数是自动抽帧功能,frameGap参数是隔多少帧进行自动抽取。
class ExtractImg(object):def __init__(self, videopath: Path, savepath: Path, delay: int = 1) -> None:self.spath = savepathself.vpath = videopathself.delay = delaycv2.namedWindow("cv", cv2.WINDOW_NORMAL)cv2.resizeWindow("cv", 640, 480)self.cap = cv2.VideoCapture(str(self.vpath))self._timeflag = 0if not savepath.exists():os.mkdir(Path(savepath))def _videoPlay(self, size: list) -> None:self.cap.set(3, size[0])self.cap.set(4, size[1])while self.cap.isOpened():ret, frame = self.cap.read()# frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)cv2.imshow("cv", frame)if cv2.waitKey(self.delay) & 0xFF == ord('c'):cv2.imwrite(str(PurePath.joinpath(self.spath,"{}.jpg".format(str(time.time())))), frame)print("保存成功")time.sleep(1)elif cv2.waitKey(self.delay) & 0xFF == 27:breakdef ExtractAll(self, frameGap: int = 3) -> None:"""这是将视频流中的帧全部抽出:frame: 跳帧:return:"""while self.cap.isOpened():self._timeflag += 1ret, frame = self.cap.read()if ret:cv2.imshow("cv", frame)if self._timeflag % frameGap == 0:cv2.imwrite(str(PurePath.joinpath(self.spath,"{}.jpg".format(str(time.time())))), frame)print("保存成功")if (cv2.waitKey(self.delay) & 0xFF == 27) or not ret:breakcv2.destroyAllWindows()self.cap.release()self._timeflag = 0def CutVideo(self) -> None:"""这是手动抽帧:return:"""ifm = input("文件中已经存在{}张图片,是否有继续添加""(Y or N):".format(len(os.listdir(self.spath))))if self.spath.exists() and ifm == 'Y':self._videoPlay(size=[640, 480])elif self.spath.exists() and ifm == 'N':return Noneelse:print("\n请输入Y(yes)或者N(no)")cv2.destroyAllWindows()self.cap.release()
2. 文件批量重命名
将文件夹下的图片进行升序的重命名。
def statistics(path: Union[str, Path], dstpath: Union[Path, str], count: int = 0, random: bool = False) -> None:"""这是存放图片的文件夹安升序重命名:param path:需要重命名的文件文件:param count:观察图片总数添加使用"""assert isinstance(path, (Path, str)), print("请输入的路径")l = os.listdir(str(path))if not Path.exists(dstpath):Path.mkdir(dstpath)# l = sorted(l)print(l)# print(l)print("存在文件{}张!".format(len(l)))if random:np.random.shuffle(l)# print(l)# 将保存图片文件中的图片按照升序的方法重命名suffix = Path(l[0]).suffixfor file in tqdm(l):src = PurePath.joinpath(path, file)dst = PurePath.joinpath(dstpath, Path(str(count + int(Path(file).stem))).with_suffix(suffix))os.rename(src, dst)
3. 文件批量移动
下面的是将文件批量按照一定规则挑选出来放到目标文件夹下。
def choosen(src: Union[str, Path] , folder: Union[Path,str] ,dst: Union[str, Path] , suffix: str) -> None:"""1.将xml/jpg文件夹中的文件名字拿出来并且在jpg/xml对应的文件夹中将名称相同的文件挑出来2.将文件夹中的文件随取出:param xmlsrc:目标xml文件:param imgsrc:frameImg文件:param dst:根据xml挑选出的img文件:return: None"""# l = os.listdir(str(xmlsrc))if not isinstance(folder,Path):pa = Path(folder)if not isinstance(src,Path):l = Path(src)# parent = src.parentfor i in l.iterdir():file = Path(i.name).with_suffix(suffix)(pa / file).rename(Path(dst) / file)
4. 将文件批量按照一定格式进行重命名
下面将文件按照5位数字的格式进行重命名 1.jpg->00001.jpg。
def batchrenames(src: Union[str, Path], dst: Union[str, Path], sorted: bool = False) -> None:"""进行特定格式的重命名:param src:原文件:param dst: 存储文件:param sorted: 是否已经有顺序,若有学按照1.jpg ->00001.jpg:return: None"""d = {1: "0000", # 这是命名格式的字典2: "000",3: "00",4: "0",5: ""}l = os.listdir(src)suffix = Path(l[0]).suffixl.sort(key=lambda x: int(x.split('.')[0]))if sorted:for obj in tqdm(l):old = PurePath.joinpath(src, obj)new = PurePath.joinpath(dst, d[len(obj.split('.')[0])] + obj.split('.')[0] + suffix)os.rename(old, new)else:# for c, i in tqdm(enumerate(l)):pass
5. 修改xml文件内容的方法
这是修改xml文件内容的代码。
def revampXml(xml_path: Union[Path, str], update_content: str) -> None:"""这是一个修改xml文件内容的方法,将xml文件爱中的类别改称另一个类别:param xml_path: 存放xml文件的路径:param xml_dw: xpath关键字:param update_content: 更新的内容:return:None"""# 打开xml文档if not isinstance(xml_path, Path):xml_path = Path(xml_path)for i in tqdm(xml_path.iterdir()):xmlfile = xml_path / f"{i}"doc = ET.parse(xmlfile)root = doc.getroot()# 查找修改路劲for obj in root.iter("object"):sub1 = obj.find("name")if sub1.text == "motorboat":# 修改标签内容sub1.text = update_content# 保存修改doc.write(xmlfile)
总结
本文介绍了计算机视觉项目中的文件批量操作与文件批量预处理技术。 掌握这些技术将使您能够高效地处理大规模的图像数据,并为计算机视觉项目的成功实施提供强大的支持。
希望本文对您在计算机视觉项目中的文件批量操作与文件批量预处理有所启发!让我们一起推动计算机视觉的发展,创造更多可能性!
以下是完整代码
# -*- coding: utf-8 -*-
# @Author : cvYouTian
# @Software: PyCharmfrom pathlib import Path, PurePath
import xml.etree.ElementTree as ET
from typing import Union
import numpy as np
# import torch
from tqdm import tqdm
import time
import cv2
import osclass ExtractImg(object):def __init__(self, videopath: Path, savepath: Path, delay: int = 1) -> None:self.spath = savepathself.vpath = videopathself.delay = delaycv2.namedWindow("cv", cv2.WINDOW_NORMAL)cv2.resizeWindow("cv", 640, 480)self.cap = cv2.VideoCapture(str(self.vpath))self._timeflag = 0if not savepath.exists():os.mkdir(Path(savepath))def _videoPlay(self, size: list) -> None:self.cap.set(3, size[0])self.cap.set(4, size[1])while self.cap.isOpened():ret, frame = self.cap.read()# frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)cv2.imshow("cv", frame)if cv2.waitKey(self.delay) & 0xFF == ord('c'):cv2.imwrite(str(PurePath.joinpath(self.spath,"{}.jpg".format(str(time.time())))), frame)print("保存成功")time.sleep(1)elif cv2.waitKey(self.delay) & 0xFF == 27:breakdef ExtractAll(self, frameGap: int = 3) -> None:"""这是将视频流中的帧全部抽出:frame: 跳帧:return:"""while self.cap.isOpened():self._timeflag += 1ret, frame = self.cap.read()if ret:cv2.imshow("cv", frame)if self._timeflag % frameGap == 0:cv2.imwrite(str(PurePath.joinpath(self.spath,"{}.jpg".format(str(time.time())))), frame)print("保存成功")if (cv2.waitKey(self.delay) & 0xFF == 27) or not ret:breakcv2.destroyAllWindows()self.cap.release()self._timeflag = 0def CutVideo(self) -> None:"""这是手动抽帧:return:"""ifm = input("文件中已经存在{}张图片,是否有继续添加""(Y or N):".format(len(os.listdir(self.spath))))if self.spath.exists() and ifm == 'Y':self._videoPlay(size=[640, 480])elif self.spath.exists() and ifm == 'N':return Noneelse:print("\n请输入Y(yes)或者N(no)")cv2.destroyAllWindows()self.cap.release()@staticmethoddef statistics(path: Union[str, Path], dstpath: Union[Path, str], count: int = 5305, random: bool = False) -> None:"""这是存放图片的文件夹安升序重命名:param path:需要重命名的文件文件:param count:观察图片总数添加使用"""assert isinstance(path, (Path, str)), print("请输入的路径")l = os.listdir(str(path))if not Path.exists(dstpath):Path.mkdir(dstpath)# l = sorted(l)print(l)# print(l)print("存在文件{}张!".format(len(l)))if random:np.random.shuffle(l)# print(l)# 将保存图片文件中的图片按照升序的方法重命名suffix = Path(l[0]).suffixfor file in tqdm(l):src = PurePath.joinpath(path, file)dst = PurePath.joinpath(dstpath, Path(str(count + int(Path(file).stem))).with_suffix(suffix))os.rename(src, dst)@staticmethoddef choosen(src: Union[str, Path]="/home/you/Desktop/2023海上高速目标检测/val", folder: Union[Path,str]="/home/you/Desktop/2023海上高速目标检测/annotations",dst: Union[str, Path]="/home/you/Desktop/2023海上高速目标检测/train", suffix: str=".xml") -> None:"""1.将xml/jpg文件夹中的文件名字拿出来并且在jpg/xml对应的文件夹中将名称相同的文件挑出来2.将文件夹中的文件随取出:param xmlsrc:目标xml文件:param imgsrc:frameImg文件:param dst:根据xml挑选出的img文件:return: None"""# l = os.listdir(str(xmlsrc))if not isinstance(folder,Path):pa = Path(folder)if not isinstance(src,Path):l = Path(src)# parent = src.parentfor i in l.iterdir():file = Path(i.name).with_suffix(suffix)(pa / file).rename(Path(dst) / file)@staticmethoddef batchrenames(src: Union[str, Path], dst: Union[str, Path], sorted: bool = False) -> None:"""进行特定格式的重命名:param src:原文件:param dst: 存储文件:param sorted: 是否已经有顺序,若有学按照1.jpg ->00001.jpg:return: None"""d = {1: "0000", # 这是命名格式的字典2: "000",3: "00",4: "0",5: ""}l = os.listdir(src)suffix = Path(l[0]).suffixl.sort(key=lambda x: int(x.split('.')[0]))if sorted:for obj in tqdm(l):old = PurePath.joinpath(src, obj)new = PurePath.joinpath(dst, d[len(obj.split('.')[0])] + obj.split('.')[0] + suffix)os.rename(old, new)else:# for c, i in tqdm(enumerate(l)):pass@staticmethoddef text(file: Union[Path, str]):l = []f = open(file)for i in f.readlines():i = i.strip()stem = Path(i).stemsuffix = Path(i).suffixn1, n2 = int(stem) - 1, int(stem) + 1l.append(str(n1) + ".xml")l.append(str(n2) + ".xml")print(l)@staticmethoddef revampXml(xml_path: Union[Path, str], update_content: str) -> None:"""这是一个修改xml文件内容的方法,将xml文件爱中的类别改称另一个类别:param xml_path: 存放xml文件的路径:param xml_dw: xpath关键字:param update_content: 更新的内容:return:None"""# 打开xml文档if not isinstance(xml_path, Path):xml_path = Path(xml_path)for i in tqdm(xml_path.iterdir()):xmlfile = xml_path / f"{i}"doc = ET.parse(xmlfile)root = doc.getroot()# 查找修改路劲for obj in root.iter("object"):sub1 = obj.find("name")if sub1.text == "motorboat":# 修改标签内容sub1.text = update_content# 保存修改doc.write(xmlfile)@staticmethoddef movefile(folder_path: Union[Path, str], dst: Union[Path, str], suffix: str) -> None:"""批量移动剪切文件:param folder_path: 原文件夹路径:param dst: 目标文件夹路径:param suffix: 移动的文件格式/后缀:return:"""if not isinstance(folder_path, Path):folder_path = Path(folder_path)# for i in folder_path.iterdir():# if i.is_dir():# ExtractImg.movefile(folder_path / i, suffix, res)# else:# if i.suffix == suffix:# res.append(str(i))# # return res if suffix is None or suffix == "" else list(filter(lambda x: str(x).endswith(suffix),res))# return resfor i in tqdm(folder_path.rglob(f"*{suffix}")):i.rename(dst / i.name)@staticmethoddef convert_box(size, box):dw, dh = 1. / size[0], 1. / size[1]x, y, w, h = (box[0] + box[1]) / 2.0 - 1, (box[2] + box[3]) / 2.0 - 1, box[1] - box[0], box[3] - box[2]return x * dw, y * dh, w * dw, h * dhif __name__ == "__main__":# 目标视频文件videopath = Path("videoSet/seabird6.mp4")# 图片保存文件savepath = Path("./dataset/imgs")# xin = Path("./VOC6detect/imgss")# savepath = Path("frameSave")# 目标xml文件# xmlpath = Path("./VOC6detect/annotations")# old = Path("/home/you/Desktop/dateset/20(pass)/seabird5")# new = Path("/home/you/Desktop/dateset/11(pass)/temp")# pa = Path("./labels/")# xin = Path()# renamepath = Path("/home/you/Desktop/dateset/4(pass)/a-1")# 实例化a = ExtractImg(videopath=videopath, savepath=savepath)a.choosen()# VOC2YOLO# a.convert_label()# 将帧全部抽出# a.ExtractAll(frameGap=8)# 手动抽帧# a.CutVideo()# 根据xml文选出对应的文件# a.choosen(xmlsrc=xmlpath, imgsrc=savepath, dst=xin)# 将数字命名的图片按照加上一个数字的方式命名# a.statistics(path=Path("./DATA/xml"), dstpath=Path("./DATA/t"), count=5305)# 对已经有顺序或者没顺序的文件进行特定格式的重命名78.jpg -> 00078.jpg# a.batchrenames(src=new, dst=old, sorted=True)# a.text("./data1.txt")# 对xml文件进行修改# a.revampXml(xml_path= "/home/you/Desktop/tools/dataset/annotations", update_content="speedboat")# 批量拿到文件夹中的某格式的文件# a.movefile(folder_path="/home/you/Desktop/网上快艇", dst=pa, suffix=".jpg")相关文章:
计算机视觉项目中的文件批量操作与文件批量预处理
计算机视觉项目中的文件批量操作与文件批量预处理 目录 数据集制作文件批量重命名文件批量移动将文件批量按照一定格式进行重命名修改xml文件内容的方法 引言 在计算机视觉项目中,文件批量操作和文件批量预处理是必不可少的步骤。它们涉及处理大量的图像文件&am…...
PHP数组转对象和对象转数组
PHP数组转对象和对象转数组 <?php function array_to_object($arr){$obj new stdClass();foreach ($arr as $key > $val) {if (is_array($val) || is_object($val)) {$obj->$key array_to_object($val);} else {$obj->$key $val;}}return $obj; } function o…...
前后端分离开发中的传参
1.post请求,后台代码使用RequestBody注解接收前端传过来的参数 PostMapping("/saveHosp") public Result SaveHosp(RequestBody HospitalSet hospitalSet){//此处省略中间代码......} 此时前端传过来的参数须为JSON格式,前端VUE传参数为&…...
mount: wrong fs type, bad option, bad superblock报错 ubuntu
问题描述 mount: wrong fs type, bad option, bad superblock Ubuntu无法挂载磁盘。 原因 很大概率是你的硬盘是NTFS。 解决 sudo apt install ntfs-3g即可。...
【图像分类】CNN+Transformer结合系列.3
介绍两篇图像分类的论文:ResMLP(arXiv2305),MetaFormer(CVPR2022),两者都与Transformer有关系,前者基于transformer结构的特点设计ResMLP,后者认为宏观架构才是Transform…...
IDA分析实例android_crackme/EasyJNI/Transformers/pingan2
文章目录 第一个实例android_crackme将32位的android_server放到手机目录下给android_server赋予root更改root用户组运行android_serverpc端端口转发安装apk,并运行app打开32位IDA并attach到进程先使用jadx看java层逻辑定位要分析的方法IDA 给两个方法打断点 第二个…...
拿捏--->求一元二次方程的根
文章目录 题目描述算法思路代码示例 题目描述 从键盘输入a, b, c的值,编程计算并输出一元二次方程ax2 bx c 0的根,当a 0时,输出“Not quadratic equation”,当a ≠ 0时,根据△ b2 - 4ac的三种情况计算并输出方程…...
深入浅出之Docker Compose详解
目录 1.Docker Compose概述 1.1 Docker Compose 定义 1.2 Docker Compose产生背景 1.3 Docker Compose 核心概念 1.4 Docker Compose 使用步骤 1.5 Docker Compose 常用命令 2. Docker Compose 实战 2.1 Docker Compose下载和卸载 2.2 Docker Compose 项目概述 2.3 Do…...
spring5源码篇(12)——spring-mvc请求流程
spring-framework 版本:v5.3.19 文章目录 一、请求流程1、处理器映射器1.1、 RequestMappingHandlerMapping1.2、获取对应的映射方法1.3、添加拦截器 2、获取合适的处理器适配器3、通过处理器适配器执行处理器方法3.1、拦截器的前置后置3.2、处理器的执行3.2.1 参数…...
风辞远的科技茶屋:来自未来的信号枪
很久之前,有位朋友问我,现在科技资讯这么发达了,你们还写啊写做什么呢? 我是这么看的。最终能够凝结为资讯的那个新闻点,其实是一系列事情最终得出的结果,而这个结果又会带来更多新的结果。其中这些“得出”…...
MongoDB教程-8
ObjectId 在之前的所有章节中,我们一直在使用MongoDB的Object Id。在本章中,我们将了解ObjectId的结构。 ObjectId是一个12字节的BSON类型,具有以下结构-- 1. 前4个字节代表自unix epoch以来的秒数 接下来的3个字节是机器标识符 接下来的2…...
Redis 理论部分
前面写了很多redis项目,今天在通过redis的理论加深redis的了解,顺便做个总结 Redis 理论部分 1.redis 速度快的原因 纯内存操作单线程操作,避免频繁的上下文切换以及资源争用的问题,多线程需要占用更多的cpu资源采用非阻塞I/O多…...
Android—Monkey用法
文章目录 Monkey知识 Monkey知识 介绍 Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中。它向系统发送伪随机的用户事件流(如按键输入、触摸屏输入、手势输入等),实现对正在开发的应用程序进行压力测试。Monkey测试是一种为了测试软…...
几个影响 cpu cache 性能因素及 cache 测试工具介绍
》内核新视界文章汇总《 文章目录 1 cache 性能及影响因素1.1 内存访问和性能比较1.2 cache line 对性能的影响1.3 L1 和 L2 缓存大小1.4 指令集并行性对 cache 性能的影响1.5 缓存关联性对 cache 的影响1.6 错误的 cacheline 共享 (缓存一致性)1.7 硬件设计 2 cpu cache benc…...
Java从入门到精通(二)· 基本语法
Java从入门到精通(二) 基本语法 一 变量 1.字面量 计算机是用来处理数据的,字面量就是告诉程序员:数据在程序中的书写格式。 特殊的字符: \n 表示换行, \t 表示一个制表符,即一个tab 2.变量…...
云安全攻防(三)之 面向云原生环境的安全体系
面向云原生环境的安全体系 根据云原生环境的构成,面向云原生环境的安全体系可包含三个层面的安全体制,它们分别是容器安全、编排系统安全和云原生应用安全,下面,我们逐步来讲解这三点: 容器安全 容器环境࿰…...
BGP汇总和破解水平分割
一,BGP的宣告问题 在BGP协议中每台运行BGP的设备上,宣告本地直连路由在BGP协议中运行BGP协议的设备来宣告,通过IGP学习到的,未运行BGP协议设备产生的路由; 在BGP协议中宣告本地路由表中路由条目时,将携带本…...
BUG:pm2启动verdaccio报错:Invalid or unexpected toke
输入命令: pm2 state verdaccio 问题描述: pm2 logs verdaccio报错翻译:数据格式错误 导致我呢提原因,没有找到运行文件, 发现问题:因为命令默认查找verdaccio是去系统盘查找。 解决方式 1:…...
Zookeeper笔记
为什么要使用Zookeeper dubbo需要一个注册中心,而Zookeeper是我们在使用Dubbo是官方推荐的注册中心 Zookeeper介绍 Zookeeper的集群机制 Zookeeper是为了其他分布式程序提供服务的,所以不能随便就挂了。Zookeeper的集群机制采取的是半数存活机制。也…...
【视觉SLAM入门】5.1. 特征提取和匹配--FAST,ORB(关键点描述子),2D-2D对极几何,本质矩阵,单应矩阵,三角测量,三角化矛盾
"不言而善应" 0. 基础知识1. 特征提取和匹配1.1 FAST关键点1.2 ORB的关键点--改进FAST1.3 ORB的描述子--BRIEF1.4 总结 2. 对极几何,对极约束2.1 本质矩阵(对极约束)2.1.1 求解本质矩阵2.1.2 恢复相机运动 R , t R,t R,…...
Spring Boot 3.0 + Java 17 微服务实战:用Gradle统一管理多模块依赖与版本,告别配置混乱
Spring Boot 3.0 Java 17 微服务实战:用Gradle统一管理多模块依赖与版本 在微服务架构中,依赖管理往往成为开发者的噩梦。想象一下,当你需要在十几个子模块中同步更新Spring Boot版本时,传统的做法是在每个模块的构建文件中逐一修…...
TD-ACC+实验系统入门指南:手把手教你搭建典型环节模拟电路
TD-ACC实验系统实战手册:从零构建典型环节电路的21个关键细节 第一次接触TD-ACC实验系统时,看着密密麻麻的接口和旋钮,我的手指悬在半空迟迟不敢落下——生怕一个错误的连接就会烧毁昂贵的运算放大器。这种忐忑直到成功捕捉到第一个完美方波信…...
Python与OPC UA实战:高效读写PLC数据
1. 为什么选择Python操作OPC UA? 在工业自动化领域,PLC(可编程逻辑控制器)就像工厂的"大脑",而OPC UA则是让这个大脑与其他系统对话的"普通话"。作为Python开发者,我们经常需要从PLC读…...
5分钟彻底告别风扇噪音!FanControl终极静音配置完全指南
5分钟彻底告别风扇噪音!FanControl终极静音配置完全指南 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/…...
知乎上线求职工具,助力毕业生破困局
知乎上线求职利器,直击毕业生痛点2026届全国普通高校毕业生预计达1270万人,再创历史新高。与此同时,AI技术加速行业重构,部分传统岗位需求收缩,大量毕业生陷入“海投”困境,难以精准定位自身。在此背景下&a…...
windows版vasp-6.5.1非Cygwin版
推荐使用oneapi版本,这个版本性能要好一点。 1.解压压缩包。 Gromacs&Vasp软.件.交.流:962946828 2.用VASP安装器添加系统环境变量(选择bin目录所在目录的父级目录)。 3.测试命令(在cmd或者powershell执行&#…...
Oracle日期处理进阶:除了EXTRACT,这些场景你还可以试试INTERVAL和TO_CHAR
Oracle日期处理进阶:解锁INTERVAL与TO_CHAR的高阶应用场景 在Oracle数据库的日常开发中,日期时间处理是每个开发者都无法回避的课题。当我们已经熟练掌握了EXTRACT这类基础函数后,往往会发现单纯提取日期部分已经无法满足复杂业务场景的需求—…...
springboot+vue基于web的校园电动车短租系统的设计系统
目录同行可拿货,招校园代理 ,本人源头供货商系统功能分析用户管理模块车辆管理模块租赁业务模块安全与风控模块统计与报表模块技术实现要点项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作同行可拿货,招校园代理 ,本人源头供货商…...
快速验证openclaw:用快马AI一键生成安装脚本与抓取原型
最近在做一个机器人抓取相关的项目,偶然发现了openclaw这个开源工具。作为一个Python实现的轻量级抓取框架,它很适合快速搭建原型。不过在实际使用过程中,我发现它的安装和配置过程有点繁琐,特别是对新手不太友好。于是尝试用InsC…...
FPGA新手避坑指南:用Xilinx MIG IP核驱动DDR3内存的完整配置流程(以MT41J256M16为例)
FPGA新手避坑指南:Xilinx MIG IP核驱动DDR3内存的完整配置流程(以MT41J256M16为例) 第一次接触FPGA与DDR3接口设计时,面对密密麻麻的芯片手册和复杂的IP核配置界面,很多工程师都会感到无从下手。本文将手把手带你完成从…...
