【pytorch】Pytorch 中的 grid 与 各种变换
Pytorch 中的 grid 与 各种变换
数学原理
**单应性(Homography) : 也就是透视变换。**单应性最初用来研究欧几里得几何中的透视和投影,而单应性一词,从词源学上来说,大致意思是“相似的绘图”。单应性的概念被引入来理解、解释和研究视觉透视,特别是从不同角度观察两个平面物体的外观差异。
Affine
Perspective
透视变换将二维图像坐标转换为三维齐次坐标,然后应用透视变换矩阵,最后将结果转换回二维坐标。通过旋转和平移将世界坐标中的点转换为相机坐标中的坐标,然后将这些坐标投影到传感器平面上。
其中 f 是焦距,(lx, ly) 是像素的物理尺寸,(cx, cy) 是相机的光学中心,以像素为单位。
方程 (1) 明确显示了针孔相机模型如何将 3D 点 (X, Y, Z) 投影到图像坐标 (u, v)
这里假设所有点**(X, Y, Z)**所在的scene是一个平面。也就是符合公式Z = αX + βY + γ。带入可得
将 P 的项与方程 (2) 中的 α、β 和 γ 混合,得到一个新的 3 x 3 未知矩阵 M,即透视变换矩阵:
为了求解 M 的项,我们必须首先将 λ=m20 X + m21 Y +m22 代入方程 (3),得到有 9 个未知数的齐次线性方程:
求解透视变换矩阵 M 的九个条目(最多一个缩放因子),以及物平面坐标 (X, Y) 与其像素值 (u, v) 之间的四个对应关系。
9个未知数,zero space为1维。因此有一个自由度,通常被设置为1。
Pytorch 官方文档解读
grid in pytorch
基础知识
grid in Pytorch
https://pytorch.org/docs/stable/generated/torch.nn.functional.grid_sample.html
grid in numpy
图像增强中的 变换api
torchvision.transforms.functional
torchvision.transforms.functional.affine(img: Tensor, angle: float, translate: List[int], scale: float, shear: List[float], interpolation: InterpolationMode = InterpolationMode.NEAREST, fill: Optional[List[float]] = None, center: Optional[List[int]] = None)
对比关系
torchvision.transforms.functional 中的 affine,通常用于图像处理和数据增强。
torch.nn.functional 中的 affine_grid 和 grid_sample 库,通常用于深度学习模型的操作和图像变换。torch.nn.functional.affine_grid 函数用于生成仿射变换的网格,torch.nn.functional.grid_sample 函数用于在输入图像上应用仿射变换。这些函数通常用于构建自定义的图像变换层或模型,以实现更灵活的图像空间变换。
另外图像变换中有perspective,而nn中没有。
torchvision.transforms.functional.perspective(img: Tensor, startpoints: List[List[int]], endpoints: List[List[int]], interpolation: InterpolationMode = InterpolationMode.BILINEAR, fill: Optional[List[float]] = None) → Tensor
img(Tensor):输入的图像,通常是一个PyTorch张量,可以是单通道或多通道的图像。startpoints(List[List[int]]):一个包含4个起始点坐标的列表,每个起始点用一个[x, y]列表表示。这些起始点用于指定透视变换的原始四边形的四个顶点。endpoints(List[List[int]]):一个包含4个目标点坐标的列表,每个目标点用一个[x, y]列表表示。这些目标点用于指定透视变换后的四边形的四个顶点。interpolation(InterpolationMode,可选):指定插值方法的枚举类型。它表示在透视变换期间如何对图像进行插值。可选的插值方法包括InterpolationMode.NEAREST(最近邻插值)和InterpolationMode.BILINEAR(双线性插值)等。fill(Optional[List[float]],可选):一个包含用于填充图像的颜色值的列表,通常表示为[R, G, B]。如果未提供此参数,则使用默认值[0, 0, 0]进行填充。startpoints和endpoints分别指定了原始四边形和目标四边形的四个顶点,通过这些顶点之间的映射关系,函数将原始图像进行透视变换。interpolation参数允许你选择插值方法以保持图像的质量。如果需要在深度学习中执行透视变换,这个函数可以用于构建自定义的图像增强层。
具体实现:
函数用于执行透视变换,它接受输入图像、原始四边形的四个顶点、变换后的四边形的四个顶点、插值方式和填充值作为参数。函数根据参数选择使用Pillow(F_pil.perspective)或PyTorch(F_t.perspective)来执行透视变换。如果输入是PIL图像,它将使用Pillow进行变换,如果输入是PyTorch张量,它将使用PyTorch进行变换。函数的返回值是变换后的图像。
def perspective(img: Tensor,startpoints: List[List[int]],endpoints: List[List[int]],interpolation: InterpolationMode = InterpolationMode.BILINEAR,fill: Optional[List[float]] = None,
) -> Tensor:"""执行给定图像的透视变换。如果图像是 Torch 张量,则预期其具有 [..., H, W] 的形状,其中 ... 表示任意数量的前导维度。Args:img (PIL 图像或张量): 要进行变换的图像。startpoints (list of list of ints): 包含四个包含两个整数的列表的列表,对应于原始图像的四个角``[左上角, 右上角, 右下角, 左下角]``。endpoints (list of list of ints): 包含四个包含两个整数的列表的列表,对应于变换后图像的四个角``[左上角, 右上角, 右下角, 左下角]``。interpolation (InterpolationMode): 期望的插值方式枚举,由:class:`torchvision.transforms.InterpolationMode` 定义。默认为 ``InterpolationMode.BILINEAR``。如果输入为张量,则仅支持 ``InterpolationMode.NEAREST`` 和 ``InterpolationMode.BILINEAR``。也可以接受对应的Pillow整数常数,如 ``PIL.Image.BILINEAR``。fill (sequence 或数字,可选): 用于填充变换后图像之外区域的像素值。如果给定一个数字,则分别用于所有波段。.. 注意::在 TorchScript 模式下,不支持单个 int/float 值,请使用长度为 1 的序列:``[value, ]``。Returns:PIL 图像或张量: 变换后的图像。"""# 检查是否处于 TorchScript 或 Tracing 模式下,如果不是,则记录 API 使用情况if not torch.jit.is_scripting() and not torch.jit.is_tracing():_log_api_usage_once(perspective)# 获取透视变换的系数,这些系数将在后续的变换中使用coeffs = _get_perspective_coeffs(startpoints, endpoints)# 如果 interpolation 是整数,将其转换为对应的 InterpolationModeif isinstance(interpolation, int):interpolation = _interpolation_modes_from_int(interpolation)elif not isinstance(interpolation, InterpolationMode):raise TypeError("Argument interpolation should be a InterpolationMode or a corresponding Pillow integer constant")# 如果输入不是 Torch 张量,则使用 Pillow 进行透视变换if not isinstance(img, torch.Tensor):pil_interpolation = pil_modes_mapping[interpolation]return F_pil.perspective(img, coeffs, interpolation=pil_interpolation, fill=fill)# 如果输入是 Torch 张量,则使用 Torch 进行透视变换return F_t.perspective(img, coeffs, interpolation=interpolation.value, fill=fill)
利用**_get_perspective_coeffs** 利用最小二乘法获取变换矩阵。
**
def** **_get_perspective_coeffs(startpoints:** **List[List[**int**]],** **endpoints:** **List[List[**int**]])** **->** **List[**float**]:**
用于计算透视变换的系数,这些系数会在透视变换时使用。函数根据给定的起始点(原始图像的四个角)和目标点(变换后图像的四个角)来计算这些系数,然后将它们返回供透视变换使用。函数内部使用了一些线性代数和矩阵运算,最终返回一个包含8个系数的列表,这些系数可以用于对图像进行透视变换。
def _get_perspective_coeffs(startpoints: List[List[int]], endpoints: List[List[int]]) -> List[float]:"""Helper function to get the coefficients (a, b, c, d, e, f, g, h) for the perspective transforms.In Perspective Transform each pixel (x, y) in the original image gets transformed as,(x, y) -> ( (ax + by + c) / (gx + hy + 1), (dx + ey + f) / (gx + hy + 1) )Args:startpoints (list of list of ints): List containing four lists of two integers corresponding to four corners``[top-left, top-right, bottom-right, bottom-left]`` of the original image.endpoints (list of list of ints): List containing four lists of two integers corresponding to four corners``[top-left, top-right, bottom-right, bottom-left]`` of the transformed image.Returns:octuple (a, b, c, d, e, f, g, h) for transforming each pixel."""# 创建一个8x8的零矩阵 a_matrix,用于存储变换的系数a_matrix = torch.zeros(2 * len(startpoints), 8, dtype=torch.float)# 使用循环迭代四个角的坐标,计算变换系数并填充 a_matrixfor i, (p1, p2) in enumerate(zip(endpoints, startpoints)):# 填充 a_matrix 的每一行a_matrix[2 * i, :] = torch.tensor([p1[0], p1[1], 1, 0, 0, 0, -p2[0] * p1[0], -p2[0] * p1[1]])a_matrix[2 * i + 1, :] = torch.tensor([0, 0, 0, p1[0], p1[1], 1, -p2[1] * p1[0], -p2[1] * p1[1]])# 创建 b_matrix,用于存储起始点坐标的矩阵并将其展平b_matrix = torch.tensor(startpoints, dtype=torch.float).view(8)# 使用最小二乘法计算变换系数 resres = torch.linalg.lstsq(a_matrix, b_matrix, driver="gels").solution# 将结果转换为列表并返回output: List[float] = res.tolist()return output
Pytorch 手写代码
perspective
# PyTorch 实现代码
import torch
import torch.nn.functional as Fdef custom_perspective_transform(image, perspective_matrix):n, c, h, w = image.shapedevice = image.device# 创建二维坐标网格grid_x, grid_y = torch.meshgrid(torch.linspace(-1, 1, w, device=device),torch.linspace(-1, 1, h, device=device))ones = torch.ones_like(grid_x)# 转换为齐次坐标grid_homogeneous = torch.stack([grid_x, grid_y, ones], dim=0).reshape(3, -1) # [3, H*W]# 应用透视变换矩阵grid_transformed = torch.mm(perspective_matrix, grid_homogeneous) # [3, H*W]# 将齐次坐标转换回普通坐标xy = (grid_transformed[:2, :] / grid_transformed[2:3, :]).t().reshape(h, w, 2)# 调整形状以适应 grid_samplexy = xy.unsqueeze(0).repeat(n, 1, 1, 1) # [N, H, W, 2]# 应用网格采样transformed_image = F.grid_sample(image, xy, align_corners=True)return transformed_image# 示例使用
# 假设 'checkerboard_tensor' 是之前创建的方格图像张量
# 'perspective_matrix' 是透视变换矩阵
transformed_checkerboard = custom_perspective_transform(checkerboard_tensor, perspective_matrix)
Perspective 可反向传播
import torch
import torch.nn.functional as F
from torch.autograd import Function
from torchvision.transforms.functional import InterpolationMode
from typing import List, Optionalclass PerspectiveTransformFunction(Function):@staticmethoddef forward(ctx, img, startpoints, endpoints, interpolation, fill):# 计算透视变换的系数coeffs = _get_perspective_coeffs(startpoints, endpoints)# 执行透视变换if not isinstance(interpolation, InterpolationMode):interpolation = InterpolationMode(interpolation)output = F.grid_sample(img, coeffs.view(1, 8, 1, 1), interpolation=interpolation, padding_mode='border', align_corners=True)# 保存需要的信息以备反向传播ctx.save_for_backward(coeffs, img)ctx.interpolation = interpolationctx.fill = fillreturn output@staticmethoddef backward(ctx, grad_output):# 获取需要的信息coeffs, img = ctx.saved_tensorsinterpolation = ctx.interpolationfill = ctx.fill# 计算梯度grad_input = F.grid_sample(grad_output, coeffs.view(1, 8, 1, 1), interpolation=interpolation, padding_mode='border', align_corners=True)return grad_input, None, None, None, Noneclass PerspectiveTransform:def __init__(self, startpoints, endpoints, interpolation=InterpolationMode.BILINEAR, fill=None):self.startpoints = startpointsself.endpoints = endpointsself.interpolation = interpolationself.fill = filldef __call__(self, img):return PerspectiveTransformFunction.apply(img, self.startpoints, self.endpoints, self.interpolation, self.fill)
使用测试案例
from torchvision.transforms.functional import to_pil_image, to_tensor
from PIL import Image# 步骤1: 生成棋盘格图像并保存到磁盘
# 创建一个函数来生成棋盘格图像
def generate_chessboard(width, height, rows, cols):image = Image.new("RGB", (width, height), (255, 255, 255))draw = ImageDraw.Draw(image)cell_width = width // colscell_height = height // rowscolor1 = (0, 0, 0)color2 = (255, 255, 255)for row in range(rows):for col in range(cols):if (row + col) % 2 == 0:color = color1else:color = color2x0 = col * cell_widthy0 = row * cell_heightx1 = x0 + cell_widthy1 = y0 + cell_heightdraw.rectangle([x0, y0, x1, y1], fill=color)image.save("chessboard.png")# 调用生成函数来生成棋盘格图像
generate_chessboard(400, 400, 8, 8)# 步骤2: 执行透视变换
# 创建一个透视变换对象
startpoints = [[0, 0], [300, 0], [300, 300], [0, 300]]
endpoints = [[50, 50], [250, 0], [250, 250], [50, 250]]
transform = PerspectiveTransform(startpoints, endpoints)# 读取生成的棋盘格图像
chessboard_img = Image.open("chessboard.png")# 将图像转换为Tensor
img_tensor = to_tensor(chessboard_img).unsqueeze(0)# 执行透视变换
transformed_img = transform(img_tensor)# 步骤3: 将变换后的图像显示或保存
output_img = to_pil_image(transformed_img.squeeze(0))
output_img.show() # 显示变换后的图像
output_img.save("transformed_chessboard.png") # 保存变换后的图像
库代码
OpenCV 文档:
Perspective
https://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html#warpperspective
Affine
https://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html#warpaffine
https://docs.opencv.org/4.x/d4/d61/tutorial_warp_affine.html
尝试代码
import torch
import torch.nn.functional as F
import numpy as np
import matplotlib.pyplot as pltdef perspective_transform(image, perspective_matrix):n, c, h, w = image.shape# 生成标准网格grid = F.affine_grid(torch.eye(2, 3).unsqueeze(0), image.size(), align_corners=False)# 将网格转换为齐次坐标homogeneous_grid = torch.cat([grid, torch.ones(n, h, w, 1, device=grid.device)], dim=-1)# 应用透视变换矩阵warped_grid = torch.matmul(homogeneous_grid, perspective_matrix.transpose(1, 2))# 将齐次坐标转换回非齐次坐标warped_grid_xy = warped_grid[..., :2] / warped_grid[..., 2:3]warped_grid_xy = warped_grid_xy.permute(0, 3, 1, 2) # 转换为 (N, C, H, W) 格式# 应用网格采样transformed_image = F.grid_sample(image, warped_grid_xy, align_corners=False, padding_mode='zeros')return transformed_image# 创建一个简单的方格图像
def create_checkerboard(h, w, square_size):img = np.zeros((h, w))s = square_sizefor y in range(0, h, s*2):for x in range(0, w, s*2):img[y:y+s, x:x+s] = 1.0img[y+s:y+s*2, x+s:x+s*2] = 1.0return img# 创建方格图像
h, w = 256, 256
square_size = 32
checkerboard = create_checkerboard(h, w, square_size)# 转换为 PyTorch 张量
checkerboard_tensor = torch.tensor(checkerboard, dtype=torch.float32).unsqueeze(0).unsqueeze(0)# 创建透视变换矩阵
perspective_matrix = torch.tensor([[1.0, 0.0, 0.0],[0.0, 1.0, 0.0],[0.0, 0.001, 1.0]
], dtype=torch.float32).unsqueeze(0)# 应用透视变换
transformed_checkerboard = perspective_transform(checkerboard_tensor, perspective_matrix)# 显示原始和变换后的图像
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.imshow(checkerboard, cmap='gray')
plt.title('Original Checkerboard')
plt.subplot(1, 2, 2)
plt.imshow(transformed_checkerboard[0, 0].detach().numpy(), cmap='gray')
plt.title('Transformed Checkerboard')
plt.show()# 测试梯度
perspective_matrix.requires_grad = True
transformed_checkerboard_grad = perspective_transform(checkerboard_tensor, perspective_matrix)
loss = transformed_checkerboard_grad.sum()
loss.backward()# 检查梯度是否存在
print("Perspective matrix gradient:", perspective_matrix.grad)
利用矩阵乘法解决这个问题。每次透视变换前,构造一个足够大的0值图像。对目标图像乘变换矩阵后,放入新建的图像中。注意不要让图像边缘超出去。
为了实现透视变换并确保梯度能够被正确计算,我们可以采取一种稍微不同的方法。这个方法包括以下步骤:
- 首先,我们会构建一个足够大的空白图像(全零值)作为变换后的画布。
- 然后,我们将使用透视变换矩阵来变换原始图像中的像素位置。
- 对于变换后的每个像素位置,我们将从原始图像中复制对应的像素值到新的位置上。
- 为了防止变换后的图像边缘超出新画布的边界,我们需要适当地选择画布的大小和变换矩阵。
这种方法可以通过矩阵乘法和索引操作来实现,允许在 PyTorch 中进行梯度的反向传播。我将编写一个示例实现来展示这个过程:
import torch
import numpy as np
import matplotlib.pyplot as pltdef apply_perspective_transform(image, perspective_matrix, output_size):n, c, h, w = image.shape# 创建输出图像(空白画布)output_image = torch.zeros(n, c, *output_size, device=image.device)# 生成网格y, x = torch.meshgrid(torch.linspace(-1, 1, h), torch.linspace(-1, 1, w))z = torch.ones_like(x)grid = torch.stack([x, y, z], dim=-1).view(-1, 3).t() # 3 x (H*W)# 应用透视变换transformed_grid = torch.mm(perspective_matrix, grid) # 3 x (H*W)# 将齐次坐标转换为笛卡尔坐标xy = transformed_grid[:2, :] / transformed_grid[2, :]xy = xy.t().view(h, w, 2)# 将变换后的坐标映射到输出图像上for i in range(h):for j in range(w):x, y = xy[i, j]if -1 <= x <= 1 and -1 <= y <= 1:# 将像素值复制到新位置xi, yi = int((x + 1) / 2 * (output_size[1] - 1)), int((y + 1) / 2 * (output_size[0] - 1))output_image[0, :, yi, xi] = image[0, :, i, j]return output_image
```



相关文章:
【pytorch】Pytorch 中的 grid 与 各种变换
Pytorch 中的 grid 与 各种变换 数学原理 **单应性(Homography) : 也就是透视变换。**单应性最初用来研究欧几里得几何中的透视和投影,而单应性一词,从词源学上来说,大致意思是“相似的绘图”。单应性的概念被引入来…...
【Linux】线程池实现
📗线程池实现(单例模式) 1️⃣线程池概念2️⃣线程池代码样例3️⃣部分问题与细节🔸类成员函数参数列表中隐含的this指针🔸单例模式🔸一个失误导致的bug 4️⃣调用线程池完成任务 1️⃣线程池概念 线程池是…...
使用Python批量上传本地maven库到nexus
背景:外包类项目开发时是调用的公司maven仓库进行开发,交付后需要将maven仓库转移到客户环境。 原理:1、打开idea运行源代码,将maven包下载到本地仓库, 2、下载包所在目录中执行脚本将本地仓库的maven包上传到客户nex…...
【Unity实战100例】Unity对Ini格式的配置文件管理和读写
目录 一.编写ini格式配置文件 二.读取解析ini文件 三.调用属性 INI 文件以文本形式存储,易于阅读和编辑。这种人可读的格式使得调整配置参数变得更加直观,不需要专门的工具。 INI 文件是一种轻量级的配置文件格式,不需要复杂的解析器或库。它的结构相对简单,适用于小到...
k8s存储卷和数据卷下
静态pv和pvc 运维负责pv:创建号持久化存储卷,申明好读写和挂载类型,以及可以提供的存储空间 Pvc开发做,要和开发沟通好,你期望的读写和挂载类型,以及存储空间 当我发布vc之后可以生成pv,还可以在…...
SQL Server 配置远程连接
Windows 安装好 SQL Server 的 SSMS,打开SSMS配置远程连接 找到 配置管理器 启用 TCP/IP 打开防火墙设置 新建入站规则 端口TCP - 特定本地端口 (1433)允许连接下一步名称完成 重启 SQL Server 服务...
vscode(visual studio code) 免密登陆服务器
1.生成密钥 首先,在本地,打开命令输入框: WinR–>弹出输入框,输入cmd,打开命令框。 然后,在命令框,输入 ssh-keygen -t rsa -C "love"按两次回车键,问你是否重写,选择…...
[redis] redis主从复制,哨兵模式和集群
一、redis的高可用 1.1 redis高可用的概念 在web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999%等等)。 高可用的计算公式是1-(宕机时间)/(宕机时…...
debian12部署Gitea服务
首先安装git、wget、sqlite,然后进行用户和组的相关设置 sudo apt install -y git wget sqlite3 新增一个git用户与一个git组 sudo adduser --system --group --disabled-password --shell /bin/bash --home /home/git --gecos Git Version Control git 给git用户设…...
js动态设置关键侦@keyframes
js动态设置关键侦keyframes 1.前置知识 关键侦keyframes规则通过在动画序列中定义关键侦的样式来控制CSS动画序列的中间步骤 keyframes slidein {from {transform: translateX(0%);}to {transform: translateX(100%);} } // from 等价于 0%;to 等价与 100% // 或…...
【WPF.NET开发】流文档
本文内容 什么是流文档?流文档类型创建流内容与流相关的类内容架构自定义文本 流文档旨在优化查看和可读性。 流文档根据运行时变量(例如,窗口大小、设备分辨率和可选的用户首选项)来动态调整和重新排列内容,而不是设…...
golang学习-结构体
1、定义 使用type 和struct 关键字来定义结构体,是值类型 格式如下: type 类型名 struct { 字段名 类型 字段名 类型 ... } 2、实例化 1、var 结构体实例 结构体类型 var p1 Person 2、使用new关键字 var p2 new(Person) 3、使用&对结构体…...
Python:enumerate() 函数
enumerate() 函数用于同时遍历索引和元素,常用于循环中。这个函数返回一个包含索引和元素的元组,可以通过解包的方式获取它们。 使用方法: enumerate(iterable, start0). iterable: 要遍历的可迭代对象。start: 索引起始值,默认…...
FPGA 移位运算与乘法
题目: 已知d为一个8位数,请在每个时钟周期分别输出该数乘1/3/7/8,并输出一个信号通知此时刻输入的d有效(d给出的信号的上升沿表示写入有效) 由题意可知: 复位信号高有效,低复位;在inpu_grant上升…...
网络安全B模块(笔记详解)- MYSQL信息收集
MYSQL信息收集 1.通过渗透机场景Kali中的渗透测试工具对服务器场景MySQL03进行服务信息扫描渗透测试(使用工具Nmap,使用必须要使用的参数),并将该操作显示结果中数据库版本信息作为Flag提交; Flag:MySQL 5.5.12 2.通过渗透机场景Kali中的渗透测试工具对服务器场景MySQL0…...
从JavaScript的角度上讲解一下xml
- XML(可扩展标记语言) XML(可扩展标记语言)是一种被设计用于存储和传输结构化数据的标记语言。它与HTML相似,但XML并没有预定义的标签,可以自定义标签及其属性。从JavaScript的角度来看,XML可以…...
Pandas实战100例 | 案例 13: 数据分类 - 使用 `cut` 对数值进行分箱
案例 13: 数据分类 - 使用 cut 对数值进行分箱 知识点讲解 在数据分析中,将连续的数值数据分类成不同的区间(或“分箱”)是一种常见的做法。Pandas 提供了 cut 函数,它可以根据你指定的分箱边界将数值数据分配到不同的类别中。 …...
python统计分析——操作案例(模拟抽样)
参考资料:用python动手学统计学 import numpy as np import pandas as pd from matplotlib import pyplot as plt import seaborn as snsdata_setpd.read_csv(r"C:\python统计学\3-4-1-fish_length_100000.csv")[length] #此处将文件路径改为自己的路…...
部署Tomcat及其负载均衡
Tomcat服务器是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选。一般来说,Tomcat虽然和Apache或者Nginx这些Web服务器一样…...
C++ 类、结构体
C 类、结构体 类可以将变量、数组和函数完美地打包在一起。 类与结构体 类的定义: class Person {private:int age,height;double money;string books[100];public:string name;void say(){cout<<"Im"<<name<<endl;}int get_age(){…...
3步搞定YOLO人脸检测:从零到生产级应用的完整实践指南
3步搞定YOLO人脸检测:从零到生产级应用的完整实践指南 【免费下载链接】yolo-face YOLO Face 🚀 in PyTorch 项目地址: https://gitcode.com/gh_mirrors/yo/yolo-face YOLO人脸检测技术正在改变计算机视觉应用的开发方式,无论你是想构…...
STM32CubeMX项目实战:从新建工程到驱动LED,一步步教你玩转HAL库(附代码解析)
STM32CubeMX实战指南:HAL库驱动LED的底层逻辑与工程化思维 第一次打开STM32CubeMX时,那种面对密密麻麻的配置选项却不知从何下手的焦虑感,相信每位嵌入式开发者都记忆犹新。不同于传统寄存器操作的直白,HAL库和图形化配置工具带来…...
告别重复编码:用快马AI自动生成软件库e7c9的高效调用代码
作为一名经常和第三方库打交道的开发者,我深刻体会到手动编写调用代码的繁琐。尤其是像e7c9这样功能强大的软件库,虽然封装完善,但每次调用都需要反复查阅文档、处理边界情况,效率实在不高。最近尝试用InsCode(快马)平台的AI辅助生…...
Hunyuan-MT-7B企业部署案例:出海SaaS公司集成Pixel Language Portal构建内部翻译中台
Hunyuan-MT-7B企业部署案例:出海SaaS公司集成Pixel Language Portal构建内部翻译中台 1. 项目背景与挑战 随着全球化业务扩张,某出海SaaS公司面临多语言支持的核心痛点: 翻译需求激增:产品文档、用户界面、客服对话等需要支持3…...
AugmentCode无限续杯插件:突破登录限制的自动化解决方案
AugmentCode无限续杯插件:突破登录限制的自动化解决方案 【免费下载链接】free-augment-code AugmentCode 无限续杯浏览器插件 项目地址: https://gitcode.com/gh_mirrors/fr/free-augment-code 痛点解析:开发者的账户管理困境 在软件开发与测试…...
3分钟找回丢失文件!FSearch让Linux搜索体验飞起来
3分钟找回丢失文件!FSearch让Linux搜索体验飞起来 【免费下载链接】fsearch A fast file search utility for Unix-like systems based on GTK3 项目地址: https://gitcode.com/gh_mirrors/fs/fsearch 你是否曾在Linux系统中花费数分钟甚至数小时寻找一个文件…...
SQLite在线查看器:浏览器中的数据库管理革命
SQLite在线查看器:浏览器中的数据库管理革命 【免费下载链接】sqlite-viewer View SQLite file online 项目地址: https://gitcode.com/gh_mirrors/sq/sqlite-viewer 在数据驱动的时代,SQLite数据库无处不在——从移动应用到桌面软件,…...
避开理论深坑:给开发者的机器学习实用入门指南(附周志华《机器学习》高效阅读路线)
避开理论深坑:给开发者的机器学习实用入门指南 作为一名开发者,你可能已经意识到机器学习正在改变我们解决问题的方式。从推荐系统到图像识别,从自然语言处理到预测分析,机器学习正在成为现代软件开发不可或缺的一部分。但当你翻开…...
ALM扩展开发教程:如何为TypeScript IDE创建自定义插件
ALM扩展开发教程:如何为TypeScript IDE创建自定义插件 【免费下载链接】alm :rose: A :cloud: ready IDE just for TypeScript :heart: 项目地址: https://gitcode.com/gh_mirrors/al/alm ALM是一款专为TypeScript和JavaScript设计的云端IDE,为开…...
Phi-4-mini-reasoning应用场景:数学建模竞赛辅助推导与公式生成
Phi-4-mini-reasoning应用场景:数学建模竞赛辅助推导与公式生成 1. 模型概述与核心能力 Phi-4-mini-reasoning是一款由微软开发的轻量级开源模型,专为数学推理、逻辑推导和多步解题等强逻辑任务设计。这个3.8B参数的模型虽然体积小巧,但在数…...
