当前位置: 首页 > news >正文

使用Python进行二维图像的三维重建

2D图像的三维重建是从一组2D图像中创建对象或场景的三维模型的过程。这个技术广泛应用于计算机视觉、机器人技术和虚拟现实等领域。

在本文中,我们将解释如何使用Python执行从2D图像到三维重建的过程。我们将使用TempleRing数据集作为示例,逐步演示这个过程。该数据集包含了在对象周围的一个环上采样的阿格里真托(Agrigento)“Dioskouroi神庙”复制品的47个视图。

三维重建的关键概念

在深入了解如何使用Python从2D图像执行三维重建的详细步骤之前,让我们首先回顾一些与这个主题相关的关键概念。

深度图

深度图是一幅图像,其中每个像素代表摄像机和场景中相应点之间的距离。深度图常用于计算机视觉和机器人技术中,用于表示场景的三维结构。

有许多不同的方法可以从2D图像计算深度图,包括立体对应、结构光和飞行时间等。在本文中,我们将使用立体对应来从示例数据集计算深度图。

Point Cloud

点云是表示对象或场景形状的三维空间中的一组点。点云常用于计算机视觉和机器人技术中,用于表示场景的三维结构。

一旦我们计算出代表场景深度的深度图,我们可以使用它来计算一个三维点云。这涉及使用有关摄像机内部和外部参数的信息,将深度图中的每个像素投影回三维空间。

网格

网格是一个由顶点、边和面连接而成的表面表示。网格常用于计算机图形学和虚拟现实中,用于表示对象或场景的形状。

一旦我们计算出代表对象或场景形状的三维点云,我们可以使用它来生成一个网格。这涉及使用诸如Marching Cubes或Poisson表面重建等算法,将表面拟合到点云上。

逐步实现

现在我们已经回顾了与2D图像的三维重建相关的一些关键概念,让我们看看如何使用Python执行这个过程。我们将使用TempleRing数据集作为示例,逐步演示这个过程。下面是一个执行Temple Ring数据集中图像的三维重建的示例代码:

安装库:

pip install numpy scipy

导入库:

#importing libraries 
import cv2
import numpy as np
import matplotlib.pyplot as plt
import os

加载TempleRing数据集的图像:

# Directory containing the dataset images
dataset_dir = '/content/drive/MyDrive/templeRing'
# Initialize the list to store images
images = []# Attempt to load the grayscale images and store them in the list
for i in range(1, 48):  # Assuming images are named templeR0001.png to templeR0047.pngimg_path = os.path.join(dataset_dir, f'templeR{i:04d}.png')img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)if img is not None:images.append(img)else:print(f"Warning: Unable to load 'templeR{i:04d}.png'")# Visualize the input images
num_rows = 5  # Specify the number of rows
num_cols = 10  # Specify the number of columns
fig, axs = plt.subplots(num_rows, num_cols, figsize=(15, 8))# Loop through the images and display them
for i, img in enumerate(images):row_index = i // num_cols  # Calculate the row index for the subplotcol_index = i % num_cols   # Calculate the column index for the subplotaxs[row_index, col_index].imshow(img, cmap='gray')axs[row_index, col_index].axis('off')# Fill any remaining empty subplots with a white background
for i in range(len(images), num_rows * num_cols):row_index = i // num_colscol_index = i % num_colsaxs[row_index, col_index].axis('off')plt.show()

03c47c3cc1e07dc9864795f4449246cf.jpeg

解释:这段代码加载灰度图像序列,将它们排列在网格布局中,并使用matplotlib显示它们。

为每个图像计算深度图:

# Directory containing the dataset images
dataset_dir = '/content/drive/MyDrive/templeRing'
# Initialize the list to store images
images = []# Attempt to load the grayscale images and store them in the list
for i in range(1, 48):  # Assuming images are named templeR0001.png to templeR0047.pngimg_path = os.path.join(dataset_dir, f'templeR{i:04d}.png')img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)if img is not None:images.append(img)else:print(f"Warning: Unable to load 'templeR{i:04d}.png'")# Initialize the list to store depth maps
depth_maps = []# Create a StereoBM object with your preferred parameters
stereo = cv2.StereoBM_create(numDisparities=16, blockSize=15)# Loop through the images to calculate depth maps
for img in images:# Compute the depth mapdisparity = stereo.compute(img, img)    # Normalize the disparity map for visualizationdisparity_normalized = cv2.normalize(disparity, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)    # Append the normalized disparity map to the list of depth mapsdepth_maps.append(disparity_normalized)# Visualize all the depth maps
num_rows = 5  # Specify the number of rows
num_cols = 10  # Specify the number of columns
fig, axs = plt.subplots(num_rows, num_cols, figsize=(15, 8))for i, depth_map in enumerate(depth_maps):row_index = i // num_cols  # Calculate the row index for the subplotcol_index = i % num_cols   # Calculate the column index for the subplotaxs[row_index, col_index].imshow(depth_map, cmap='jet')axs[row_index, col_index].axis('off')# Fill any remaining empty subplots with a white background
for i in range(len(depth_maps), num_rows * num_cols):row_index = i // num_colscol_index = i % num_colsaxs[row_index, col_index].axis('off')plt.show()

解释:这段代码负责使用Stereo Block Matching(StereoBM)算法从一系列立体图像中计算深度图。它遍历灰度立体图像列表,并为每一对相邻图像计算深度图。

可视化每个图像的深度图:

# Initialize an accumulator for the sum of depth maps
sum_depth_map = np.zeros_like(depth_maps[0], dtype=np.float64)
# Compute the sum of all depth maps
for depth_map in depth_maps:sum_depth_map += depth_map.astype(np.float64)
# Calculate the mean depth map by dividing the sum by the number of depth maps
mean_depth_map = (sum_depth_map / len(depth_maps)).astype(np.uint8)
# Display the mean depth map
plt.figure(figsize=(8, 6))
plt.imshow(mean_depth_map, cmap='jet')
plt.title('Mean Depth Map')
plt.axis('off')
plt.show()

输出:

2707fa661da54abeb2386179e16b6ecb.jpeg

解释:这段代码通过累加深度图来计算平均深度图。然后,通过将总和除以深度图的数量来计算平均值。最后,使用jet颜色图谱显示平均深度图以进行可视化。

从平均深度图计算三维点云

# Initialize an accumulator for the sum of depth maps
sum_depth_map = np.zeros_like(depth_maps[0], dtype=np.float64)
# Compute the sum of all depth maps
for depth_map in depth_maps:sum_depth_map += depth_map.astype(np.float64)# Calculate the mean depth map by dividing the sum by the number of depth maps
mean_depth_map = (sum_depth_map / len(depth_maps)).astype(np.uint8)# Display the mean depth map
plt.figure(figsize=(8, 6))
plt.imshow(mean_depth_map, cmap='jet')
plt.title('Mean Depth Map')
plt.axis('off')
plt.show()

1b32de06ed9913c45fa573d4f5631e8c.jpeg

解释:这段代码通过对深度图进行累加来计算平均深度图。然后,通过将总和除以深度图的数量来计算平均值。最后,使用Jet颜色映射来可视化显示平均深度图。

计算平均深度图的三维点云

#converting into point cloud 
points_3D = cv2.reprojectImageTo3D(mean_depth_map.astype(np.float32), np.eye(4))

解释:该代码将包含点云中点的三维坐标,并且您可以使用这些坐标进行三维重建。

点云生成网格

安装库

!pip install numpy scipy

导入库

#importing libraries 
from scipy.spatial import Delaunay
from skimage import measure
from skimage.measure import marching_cubes

生成网格

verts, faces, normals, values = measure.marching_cubes(points_3D)

解释:该代码将Marching Cubes算法应用于3D点云以生成网格。它返回定义结果3D网格的顶点、面、顶点法线和标量值。

可视化网格

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(verts[:, 0], verts[:, 1], verts[:, 2], triangles=faces)
plt.show()

输出:

f151ba53e9d647b918eed7586832aa31.png

解释:该代码使用matplotlib可视化网格。它创建一个3D图并使用ax.plot_trisurf方法将网格添加到其中。

这段代码从Temple Ring数据集加载图像,并使用块匹配(block matching)进行每个图像的深度图计算,然后通过平均所有深度图来计算平均深度图,并使用它来计算每个像素的三维点云。最后,它使用Marching Cubes算法从点云生成网格并进行可视化。

结果比较

# importing the libraries
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# Create a figure with two subplots
fig, axs = plt.subplots(1, 2, figsize=(10, 5))# Visualize the original image in the first subplot
axs[0].imshow(images[0], cmap='gray')
axs[0].axis('off')
axs[0].set_title('Original')# Visualize the reconstructed mesh in the second subplot
ax = fig.add_subplot(1, 2, 2, projection='3d')
ax.plot_trisurf(verts[:, 0], verts[:, 1], verts[:, 2], triangles=faces)
ax.set_title('Reconstructed')# Show the figure
plt.show()

ed0badbd09152e13a56cf81dd247bdf9.jpeg

解释:在此代码中,使用matplotlib创建了包含两个子图的图形。在第一个图中,显示了来自数据集的原始图像。在第二个图中,使用3D三角形表面图可视化了重建的3D网格。

方法2

以下是执行来自TempleRing数据集图像的3D重建的另一个示例代码:

引入模块:

import cv2
import numpy as np
import matplotlib.pyplot as plt
from google.colab.patches import cv2_imshow

加载两个Temple Ring数据集图像:

# Load the PNG images (replace with your actual file paths)
image1 = cv2.imread('/content/drive/MyDrive/templeRing/templeR0001.png')
image2 = cv2.imread('/content/drive/MyDrive/templeRing/templeR0002.png'

解释:该代码使用OpenCV的cv2.imread函数从TempleRing数据集加载两个图像。

转换为灰度图:

# Convert images to grayscale
gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)

该代码使用OpenCV将两个图像转换为灰度图像。它们以单通道表示,其中每个像素的值表示其强度,并且没有颜色通道。

查找SIFT关键点和描述符:

# Initialize the SIFT detector
sift = cv2.SIFT_create()
# Detect keypoints and compute descriptors for both images
kp1, des1 = sift.detectAndCompute(gray1, None)
kp2, des2 = sift.detectAndCompute(gray2, None)

该代码使用尺度不变特征变换(SIFT)算法在两个图像中查找关键点和描述符。它使用OpenCV的cv2.SIFT_create()函数创建一个SIFT对象,并调用其detectAndCompute方法来计算关键点和描述符。

使用FLANN匹配器匹配描述符:

# Create a FLANN-based Matcher object
flann = cv2.FlannBasedMatcher({'algorithm': 0, 'trees': 5}, {})
# Match the descriptors using KNN (k-nearest neighbors)
matches = flann.knnMatch(des1, des2, k=2)

解释:该代码使用Fast Library for Approximate Nearest Neighbors(FLANN)匹配器对描述符进行匹配。它使用OpenCV的cv2.FlannBasedMatcher函数创建FLANN匹配器对象,并调用其knnMatch方法来找到每个描述符的k个最近邻。

使用Lowe的比率测试筛选出好的匹配项

# Apply Lowe's ratio test to select good matches
good_matches = []
for m, n in matches:if m.distance < 0.7 * n.distance:good_matches.append(m)

解释:该代码使用Lowe的比率测试筛选出好的匹配项。它使用最近邻和次近邻之间距离比的阈值来确定匹配是否良好。

提取匹配的关键点

# Extract matched keypoints
src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)

解释:该代码从两组关键点中提取匹配的关键点,这些关键点将用于估算对齐两个图像的变换。这些关键点的坐标存储在'src_pts'和'dst_pts'中。

使用RANSAC找到单应矩阵

# Find the homography matrix using RANSAC
H, _ = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)

在这段代码中,它使用RANSAC算法基于匹配的关键点计算描述两个图像之间的变换的单应矩阵。单应矩阵后来可以用于拉伸或变换一个图像,使其与另一个图像对齐。

使用单应矩阵将第一个图像进行变换

# Perform perspective transformation to warp image1 onto image2
height, width = image2.shape[:2]
result = cv2.warpPerspective(image1, H, (width, height))
# Display the result
cv2_imshow(result)

28ca168db5a14696349025da381f0a8a.jpeg

解释:该代码使用单应矩阵和OpenCV的cv2.warpPerspective函数将第一个图像进行变换。它指定输出图像的大小足够大,可以容纳两个图像,然后呈现结果图像。

显示原始图像和重建图像

# Display the original images and the reconstructed image side by side
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(12, 4))
ax1.imshow(cv2.cvtColor(image1, cv2.COLOR_BGR2RGB))
ax1.set_title('Image 1')
ax1.axis('off')
ax2.imshow(cv2.cvtColor(image2, cv2.COLOR_BGR2RGB))
ax2.set_title('Image 2')
ax2.axis('off')
ax3.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
ax3.set_title('Reconstructed Image')
ax3.axis('off')
plt.show()

输出:

84885befac51176bdd57a076d982f6e6.jpeg

解释:这段代码展示了在一个具有三个子图的单一图形中可视化原始图像和重建图像的过程。它使用matplotlib库显示图像,并为每个子图设置标题和轴属性。

不同的可能方法

有许多不同的方法和算法可用于从2D图像执行3D重建。选择的方法取决于诸如输入图像的质量、摄像机校准信息的可用性以及重建的期望准确性和速度等因素。

一些常见的从2D图像执行3D重建的方法包括立体对应、运动结构和多视图立体。每种方法都有其优点和缺点,对于特定应用来说,最佳方法取决于具体的要求和约束。

结论

总的来说,本文概述了使用Python从2D图像进行3D重建的过程。我们讨论了深度图、点云和网格等关键概念,并使用TempleRing数据集演示了使用两种不同方法逐步进行的过程。我们希望本文能帮助您更好地理解从2D图像进行3D重建以及如何使用Python实现这一过程。有许多可用于执行3D重建的不同方法和算法,我们鼓励您进行实验和探索,以找到最适合您需求的方法。

·  END  ·

HAPPY LIFE

b6791b364b263441b51c0b6b8fb520c8.png

本文仅供学习交流使用,如有侵权请联系作者删除

相关文章:

使用Python进行二维图像的三维重建

2D图像的三维重建是从一组2D图像中创建对象或场景的三维模型的过程。这个技术广泛应用于计算机视觉、机器人技术和虚拟现实等领域。 在本文中&#xff0c;我们将解释如何使用Python执行从2D图像到三维重建的过程。我们将使用TempleRing数据集作为示例&#xff0c;逐步演示这个过…...

go-zero微服务的使用

一、入门案例 1、使用goland创建一个工程 2、新建一个user.proto syntax "proto3";package user; // 这个地方表示生成的go的包名叫user option go_package "./user";message UserInfoRequest {int64 userId 1; }message UserInfoResponse {int64 user…...

Java排序算法之基数排序

基数排序&#xff08;Radix Sort&#xff09;是一种线性时间复杂度的排序算法&#xff0c;其时间复杂度为O(d(nk))&#xff0c;其中d是数字的位数&#xff0c;k是进制数。基数排序是一种非比较排序算法&#xff0c;它按照数位的大小来进行排序。它可以处理正整数、负整数和小数…...

Ubuntu20.0中安装Gradle

下载Gradle到temp文件夹 wget https://services.gradle.org/distributions/gradle-8.3-bin.zip -P /tmp 然后解压文件到/opt/gradle目录 sudo unzip -d /opt/gradle /tmp/gradle-8.3.zip 配置Gradle环境变量 接下来我们会创建一个gradle.sh文件来保存Gradle的环境变量 sudo…...

【Java并发编程六】多线程越界问题

ArrayList()越界错误 import java.util.ArrayList; public class myTest implements Runnable {static ArrayList<Integer> a new ArrayList<>(10);public static void main(String[] args) throws InterruptedException {Thread t1 new Thread(new myTest());T…...

聊聊httpclient的disableConnectionState

序 本文主要研究一下httpclient的disableConnectionState disableConnectionState org/apache/http/impl/client/HttpClientBuilder.java /*** Disables connection state tracking.*/public final HttpClientBuilder disableConnectionState() {connectionStateDisabled t…...

Tomcat web.xml文件中的mime-mapping

在Tomcat安装目录的conf/web.xml文件中&#xff0c;定义了大量的<mime-mapping>元素&#xff0c;例如&#xff1a; 其中<extension>指定了文件的扩展名&#xff0c;<mime-type>指定了mime类型&#xff0c;放在<mime-mapping>元素中&#xff0c;就是将…...

【Java 进阶篇】JQuery 事件绑定:`on` 与 `off` 的奇妙舞曲

在前端开发的舞台上&#xff0c;用户与页面的互动是一场精彩的表演。而 JQuery&#xff0c;作为 JavaScript 的一种封装库&#xff0c;为这场表演提供了更为便捷和优雅的事件绑定方式。其中&#xff0c;on 和 off 两位主角&#xff0c;正是这场奇妙舞曲中的核心演员。在这篇博客…...

模块化Common JS 和 ES Module

目录 历程 1.几个函数&#xff1a;全局变量的污染&#xff0c;模块间没有联系 2.对象&#xff1a;暴露成员&#xff0c;外部可修改 3.立即执行函数&#xff1a;闭包实现模块私有作用域 common JS module和Module 过程 模块依赖&#xff1a;深度优先遍历、父 -> 子 -…...

基于java web个人财务管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…...

soc估计:DESIGN AND DEVELOPMENT OF SoC ESTIMATION MODEL USING MACHINE LEARNING

这是一篇印度那边学生的毕业论文&#xff0c;唯一要记录的是里面提到了一个特征构造的思想&#xff0c;记录如下&#xff1a; 论文思想&#xff1a; 特征选用速度、电流、电压、温度、平均电压、平均电流、平均速度&#xff0c;模型用cnnlstmlrlr 平均特征计算方式&#xff1a;…...

2、LeetCode之两数相加

给你两个非空的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照逆序的方式存储的&#xff0c;并且每个节点只能存储一位数字。请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。你可以假设除了数字0之外&#xff0c;这两个数都不会以0开头。 输入&am…...

redis三种集群方式

redis有三种集群方式&#xff1a;主从复制&#xff0c;哨兵模式和集群。 1.主从复制 主从复制原理&#xff1a; 从服务器连接主服务器&#xff0c;发送SYNC命令&#xff1b; 主服务器接收到SYNC命名后&#xff0c;开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所…...

Java --- JVM之垃圾回收相关算法

目录 一、垃圾标记算法 1.1、垃圾标记阶段&#xff1a;对象存活判断 1.2、引用计数算法 1.3、可达性分析算法 1.4、GC Roots 二、对象的finalization机制 2.1、生存还是死亡&#xff1f; 三、查看GC Roots 3.1、使用MAT查看 四、使用JProfiler分析OOM 五、清除阶段算…...

CentOS 7.9 安装 nginx

系统版本 # cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core)搜索nginx相关的软件包 yum search nginx显示已安装的与 “nginx” 相关的软件包 yum list | grep nginx列出可用的 Nginx 软件包 yum list nginx --showduplicates安装 Nginx yum install -y ng…...

Newman

近期在复习Postman的基础知识&#xff0c;在小破站上跟着百里老师系统复习了一遍&#xff0c;也做了一些笔记&#xff0c;希望可以给大家一点点启发。 一&#xff09;如何安装Newman 1、下载并安装NodeJs 在官网下载NodeJs&#xff1a; Download | Node.js&#xff08;官网的…...

Transformer中WordPiece/BPE等不同编码方式详解以及优缺点

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…...

Ubuntu20.04安装Beyond Compare 4.4.7

参考链接&#xff1a; 1.Ubuntu20.04 Beyond Compare 4.3.7 安装 2.Ubuntu20.04安装Beyond Compare 4.3.7...

制作含有音频、视频的网页

参考代码如下 <!DOCTYPE html> <html> <head><title>视频音乐网页</title> </head> <body><!-- 视频 --><video width"320" height"240" controls><source src"movie.mp4" type"…...

QPair的介绍及用法

QPair是一个模板类&#xff0c;它存储一对值&#xff08;key&#xff0c;value&#xff09;&#xff0c;可以是不同的数据类型。QPair的用法有以下几个方面&#xff1a; QPair的构造函数有以下几种形式&#xff1a; QPair()&#xff1a;默认构造函数&#xff0c;创建一个空的QP…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...