Eggs and Egg Info

本文介绍了Python Eggs的概念及其两种主要格式:`.egg` 和 `.egg-info`。这两种格式分别适用于不同的应用场景,前者更适合于发布和轻松卸载或升级代码,而后者则更侧重于向后兼容性和安装简便性。
----------------------
Eggs and their Formats
----------------------


A "Python egg" is a logical structure embodying the release of a
specific version of a Python project, comprising its code, resources,
and metadata. There are multiple formats that can be used to physically
encode a Python egg, and others can be developed. However, a key
principle of Python eggs is that they should be discoverable and
importable. That is, it should be possible for a Python application to
easily and efficiently find out what eggs are present on a system, and
to ensure that the desired eggs' contents are importable.


There are two basic formats currently implemented for Python eggs:


1. ``.egg`` format: a directory or zipfile *containing* the project's
   code and resources, along with an ``EGG-INFO`` subdirectory that
   contains the project's metadata


2. ``.egg-info`` format: a file or directory placed *adjacent* to the
   project's code and resources, that directly contains the project's
   metadata.


Both formats can include arbitrary Python code and resources, including
static data files, package and non-package directories, Python
modules, C extension modules, and so on.  But each format is optimized
for different purposes.


The ``.egg`` format is well-suited to distribution and the easy
uninstallation or upgrades of code, since the project is essentially
self-contained within a single directory or file, unmingled with any
other projects' code or resources.  It also makes it possible to have
multiple versions of a project simultaneously installed, such that
individual programs can select the versions they wish to use.


The ``.egg-info`` format, on the other hand, was created to support
backward-compatibility, performance, and ease of installation for system
packaging tools that expect to install all projects' code and resources
to a single directory (e.g. ``site-packages``).  Placing the metadata
in that same directory simplifies the installation process, since it
isn't necessary to create ``.pth`` files or otherwise modify
``sys.path`` to include each installed egg.


Its disadvantage, however, is that it provides no support for clean
uninstallation or upgrades, and of course only a single version of a
project can be installed to a given directory. Thus, support from a
package management tool is required. (This is why setuptools' "install"
command refers to this type of egg installation as "single-version,
externally managed".)  Also, they lack sufficient data to allow them to
be copied from their installation source.  easy_install can "ship" an
application by copying ``.egg`` files or directories to a target
location, but it cannot do this for ``.egg-info`` installs, because
there is no way to tell what code and resources belong to a particular
egg -- there may be several eggs "scrambled" together in a single
installation location, and the ``.egg-info`` format does not currently
include a way to list the files that were installed.  (This may change
in a future version.)
import serial import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation import time from matplotlib.patches import Rectangle, Circle from pylab import mpl mpl.rcParams["font.sans-serif"] = ["SimHei"] mpl.rcParams["axes.unicode_minus"] = False class EggCounter: def __init__(self): self.grid_size = (8, 8) self.cover_width = 100 # 宽度100mm self.cell_size = self.cover_width / 8 self.background = None self.bg_alpha = 0.1 self.next_id = 0 self.tracked_eggs = [] # 跟踪的鸡蛋对象 self.max_missed = 5 self.depth_threshold = 15 self.min_points = 3 self.exit_threshold = 30 # 右侧出口触发位置(mm),传送方向从左到右 self.total_count = 0 self.speed_estimation = [] # 用于速度估计的历史位置 def _grid_to_physical(self, i, j): """将网格坐标转换为物理坐标(传送方向从左到右)""" x = (j - 3.5) * self.cell_size # X: 传送方向(从左到右) y = (i - 3.5) * self.cell_size # Y: 宽度方向(垂直于传送) return x, y def _cluster_points(self, mask): """对前景点进行聚类并返回中心坐标""" clusters = [] visited = np.zeros_like(mask, dtype=bool) def dfs(i, j, points): stack = [(i, j)] while stack: x, y = stack.pop() if visited[x, y] or not mask[x, y]: continue visited[x, y] = True points.append((x, y)) for dx in (-1, 0, 1): for dy in (-1, 0, 1): nx, ny = x+dx, y+dy if 0 <= nx < 8 and 0 <= ny < 8: stack.append((nx, ny)) return points for i in range(8): for j in range(8): if mask[i, j] and not visited[i, j]: cluster = dfs(i, j, []) if len(cluster) >= self.min_points: centers = [self._grid_to_physical(*p) for p in cluster] cx = np.mean([c[0] for c in centers]) cy = np.mean([c[1] for c in centers]) clusters.append((cx, cy)) return clusters def _update_background(self, frame): """动态更新背景模型""" if self.background is None: self.background = frame.copy() else: foreground = (self.background - frame) > self.depth_threshold self.background[~foreground] = ( (1 - self.bg_alpha) * self.background[~foreground] + self.bg_alpha * frame[~foreground] ) def _match_and_track(self, current_eggs): """匹配当前帧检测到的鸡蛋与跟踪目标""" # 如果没有跟踪目标,全部初始化为新目标 if not self.tracked_eggs: for pos in current_eggs: self.tracked_eggs.append({ 'id': self.next_id, 'pos': pos, 'history': [pos], # 位置历史用于速度估计 'counted': False, 'missed': 0 }) self.next_id += 1 return # 计算目标间的距离成本矩阵 cost_matrix = np.zeros((len(self.tracked_eggs), len(current_eggs))) for i, egg in enumerate(self.tracked_eggs): for j, pos in enumerate(current_eggs): # 使用欧氏距离作为匹配成本 dist = np.sqrt((egg['pos'][0]-pos[0])**2 + (egg['pos'][1]-pos[1])**2) cost_matrix[i, j] = dist # 使用匈牙利算法进行匹配 row_idx, col_idx = linear_sum_assignment(cost_matrix) # 更新匹配的目标 matched_targets = set() matched_detections = set() for i, j in zip(row_idx, col_idx): if cost_matrix[i, j] < 20: # 距离阈值20mm self.tracked_eggs[i]['pos'] = current_eggs[j] self.tracked_eggs[i]['history'].append(current_eggs[j]) if len(self.tracked_eggs[i]['history']) > 5: self.tracked_eggs[i]['history'].pop(0) self.tracked_eggs[i]['missed'] = 0 matched_targets.add(i) matched_detections.add(j) # 处理未匹配的目标(丢失) for i, egg in enumerate(self.tracked_eggs): if i not in matched_targets: egg['missed'] += 1 # 添加新的检测目标 for j, pos in enumerate(current_eggs): if j not in matched_detections: self.tracked_eggs.append({ 'id': self.next_id, 'pos': pos, 'history': [pos], 'counted': False, 'missed': 0 }) self.next_id += 1 def process_frame(self, frame): """ 处理一帧深度数据并返回检测到的鸡蛋位置 :param frame: 8x8深度矩阵 (单位:mm) :return: (当前检测到的鸡蛋位置, 总计数) """ # 1. 更新背景模型 self._update_background(frame) # 2. 前景检测 (鸡蛋深度小于背景) foreground = (self.background - frame) > self.depth_threshold # 3. 聚类检测到的鸡蛋 current_eggs = self._cluster_points(foreground) # 4. 目标跟踪与匹配 self._match_and_track(current_eggs) # 5. 计数逻辑(鸡蛋从右侧离开时计数) for egg in self.tracked_eggs.copy(): # 如果鸡蛋在出口区域且未计数 if not egg['counted'] and egg['pos'][0] >= self.exit_threshold: self.total_count += 1 egg['counted'] = True # 标记为已计数但继续跟踪直到离开视野 # 移出检测区域(右侧太远或宽度方向超出范围) if abs(egg['pos'][1]) > 50 or egg['pos'][0] > 60: self.tracked_eggs.remove(egg) return [egg['pos'] for egg in self.tracked_eggs if not egg['counted']], self.total_count def init_serial(port='COM12', baudrate=115200): """初始化串口连接""" return serial.Serial(port, baudrate, timeout=10) def create_blackwhite_colormap(): """创建黑白渐变色图""" colors = [(0.95, 0.95, 0.95), (0, 0, 0)] # 浅灰到黑 return plt.cm.colors.LinearSegmentedColormap.from_list('bw', colors, N=256) def init_plot(): """初始化深度图显示(传送方向从左到右)""" fig = plt.figure(figsize=(14, 7)) fig.suptitle('VL53L5CX 鸡蛋计数系统(传送方向:左→右)', fontsize=16) # 深度图区域 ax1 = fig.add_subplot(121) cmap = create_blackwhite_colormap() img = ax1.imshow(np.zeros((8,8)), cmap=cmap, vmin=0, vmax=500) plt.colorbar(img, label='距离(mm)', ax=ax1) ax1.set_title('8x8 深度图') ax1.set_xlabel('传送方向(左→右)') ax1.set_ylabel('宽度方向') # 添加传送带表示(红色表示出口) ax1.add_patch(Rectangle([-0.5, -0.5], 8, 8, fill=False, edgecolor='red', linestyle='--')) ax1.text(7.5, 3.5, '→', color='red', fontsize=20, ha='center') # 传送方向箭头 # 鸡蛋位置可视化区域 ax2 = fig.add_subplot(122) ax2.set_xlim(-60, 60) ax2.set_ylim(-60, 60) ax2.set_title('鸡蛋位置检测') ax2.set_xlabel('传送方向(mm) (左→右)') ax2.set_ylabel('宽度方向(mm)') # 添加检测区域和计数线 ax2.add_patch(Rectangle([-50, -50], 100, 100, fill=False, edgecolor='blue')) ax2.axvline(x=30, color='r', linestyle='--', alpha=0.7) # 出口计数线 ax2.text(32, -45, '计数线', color='r', rotation=90) # 添加传送方向箭头 ax2.arrow(-40, 50, 70, 0, head_width=5, head_length=5, fc='r', ec='r') ax2.text(0, 55, '传送方向', color='r', ha='center') # 鸡蛋计数显示 count_text = ax2.text(0, 45, '鸡蛋计数: 0', ha='center', va='center', fontsize=24, color='green', bbox=dict(facecolor='white', alpha=0.8)) # 帧率显示 fps_text = ax2.text(0, -45, 'FPS: 0.0', ha='center', va='center', fontsize=12, color='blue') # 当前跟踪目标显示 track_text = ax2.text(40, -45, '跟踪目标: 0', ha='left', va='center', fontsize=12, color='purple') # 鸡蛋位置点容器 egg_points = ax2.scatter([], [], s=100, c='red', edgecolors='black', alpha=0.7) return fig, img, ax2, count_text, fps_text, track_text, egg_points def update_frame(frame, ser, img, ax, count_text, fps_text, track_text, egg_points, counter, last_time): """更新深度图帧并处理鸡蛋计数(传送方向从左到右)""" current_time = time.time() fps = 1 / (current_time - last_time[0]) if current_time != last_time[0] else 0 last_time[0] = current_time try: # 读取串口数据 data = ser.readline().decode('utf-8').strip() if data:# and data.startswith('[') and data.endswith(']'): # 处理数据格式: [123.4, 125.6, ...] #data = data[1:-1] # 移除方括号 distances = list(map(float, data.split(','))) if len(distances) == 64: depth_map = np.array(distances).reshape(8,8) # 更新深度图显示 img.set_array(depth_map) img.autoscale() # 鸡蛋检测与计数 eggs, total_count = counter.process_frame(depth_map) # 更新鸡蛋位置散点图 if eggs: x_pos = [egg[0] for egg in eggs] y_pos = [egg[1] for egg in eggs] egg_points.set_offsets(np.column_stack([x_pos, y_pos])) else: egg_points.set_offsets([]) # 更新计数显示 count_text.set_text(f'鸡蛋计数: {total_count}') fps_text.set_text(f'FPS: {fps:.1f}') track_text.set_text(f'跟踪目标: {len(counter.tracked_eggs)}') except Exception as e: print(f"Error: {e}") return img, egg_points, count_text, fps_text, track_text def main(): ser = init_serial() counter = EggCounter() fig, img, ax2, count_text, fps_text, track_text, egg_points = init_plot() last_time = [time.time()] ani = animation.FuncAnimation( fig, update_frame, fargs=(ser, img, ax2, count_text, fps_text, track_text, egg_points, counter, last_time), interval=50, blit=True ) plt.tight_layout() plt.subplots_adjust(top=0.9) plt.show() ser.close() if __name__ == "__main__": from scipy.optimize import linear_sum_assignment # 确保导入 main()
09-11
import serial import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation import time from matplotlib.patches import Rectangle, Circle from pylab import mpl from scipy.optimize import linear_sum_assignment mpl.rcParams["font.sans-serif"] = ["SimHei"] mpl.rcParams["axes.unicode_minus"] = False import numpy as np from scipy.optimize import linear_sum_assignment class EggCounter: def __init__(self): self.grid_size = (8, 8) self.cover_width = 100 # 宽度100mm self.cell_size = self.cover_width / 8 self.background = None self.bg_alpha = 0.1 self.next_id = 0 self.tracked_eggs = [] # 跟踪的鸡蛋对象 self.max_missed = 5 self.depth_threshold = 15 self.min_points = 3 self.exit_threshold = 30 # 右侧出口触发位置(mm),传送方向从左到右 self.total_count = 0 self.speed_estimation = [] # 用于速度估计的历史位置 def _grid_to_physical(self, i, j): """将网格坐标转换为物理坐标(传送方向从左到右)""" x = (j - 3.5) * self.cell_size # X: 传送方向(从左到右) y = (i - 3.5) * self.cell_size # Y: 宽度方向(垂直于传送) return x, y def _cluster_points(self, mask): """对前景点进行聚类并返回中心坐标""" # 确保mask是二维数组 if mask.ndim == 1 or mask.shape != self.grid_size: try: mask = mask.reshape(self.grid_size) except ValueError: print(f"无法重塑数组形状: {mask.shape} -> {self.grid_size}") return [] clusters = [] visited = np.zeros(self.grid_size, dtype=bool) def dfs(i, j, points): """深度优先搜索聚类点""" stack = [(i, j)] while stack: x, y = stack.pop() # 确保索引在有效范围内 if x < 0 or x >= self.grid_size[0] or y < 0 or y >= self.grid_size[1]: continue if visited[x, y] or not mask[x, y]: continue visited[x, y] = True points.append((x, y)) # 8邻域搜索 for dx in (-1, 0, 1): for dy in (-1, 0, 1): if dx == 0 and dy == 0: continue nx, ny = x + dx, y + dy # 确保新坐标在网格内 if 0 <= nx < self.grid_size[0] and 0 <= ny < self.grid_size[1]: stack.append((nx, ny)) return points for i in range(self.grid_size[0]): for j in range(self.grid_size[1]): if mask[i, j] and not visited[i, j]: cluster = dfs(i, j, []) if len(cluster) >= self.min_points: centers = [self._grid_to_physical(*p) for p in cluster] cx = np.mean([c[0] for c in centers]) cy = np.mean([c[1] for c in centers]) clusters.append((cx, cy)) return clusters def _update_background(self, frame): """动态更新背景模型""" # 确保frame是二维数组 if frame.ndim == 1 or frame.shape != self.grid_size: try: frame = frame.reshape(self.grid_size) except ValueError: print(f"无法重塑背景数组形状: {frame.shape} -> {self.grid_size}") return if self.background is None: self.background = frame.copy().astype(float) else: # 确保背景和当前帧形状一致 if self.background.shape != frame.shape: try: self.background = self.background.reshape(frame.shape) except ValueError: print("形状不匹配,无法更新背景") return foreground = (self.background - frame) > self.depth_threshold self.background[~foreground] = ( (1 - self.bg_alpha) * self.background[~foreground] + self.bg_alpha * frame[~foreground] ) def _match_and_track(self, current_eggs): """匹配当前帧检测到的鸡蛋与跟踪目标""" # 如果没有跟踪目标,全部初始化为新目标 if not self.tracked_eggs: for pos in current_eggs: self.tracked_eggs.append({ 'id': self.next_id, 'pos': pos, 'history': [pos], # 位置历史用于速度估计 'counted': False, 'missed': 0 }) self.next_id += 1 return # 计算目标间的距离成本矩阵 cost_matrix = np.zeros((len(self.tracked_eggs), len(current_eggs))) for i, egg in enumerate(self.tracked_eggs): for j, pos in enumerate(current_eggs): # 使用欧氏距离作为匹配成本 dist = np.sqrt((egg['pos'][0]-pos[0])**2 + (egg['pos'][1]-pos[1])**2) cost_matrix[i, j] = dist # 使用匈牙利算法进行匹配 row_idx, col_idx = linear_sum_assignment(cost_matrix) # 更新匹配的目标 matched_targets = set() matched_detections = set() for i, j in zip(row_idx, col_idx): if cost_matrix[i, j] < 20: # 距离阈值20mm self.tracked_eggs[i]['pos'] = current_eggs[j] self.tracked_eggs[i]['history'].append(current_eggs[j]) if len(self.tracked_eggs[i]['history']) > 5: self.tracked_eggs[i]['history'].pop(0) self.tracked_eggs[i]['missed'] = 0 matched_targets.add(i) matched_detections.add(j) # 处理未匹配的目标(丢失) for i, egg in enumerate(self.tracked_eggs): if i not in matched_targets: egg['missed'] += 1 # 添加新的检测目标 for j, pos in enumerate(current_eggs): if j not in matched_detections: self.tracked_eggs.append({ 'id': self.next_id, 'pos': pos, 'history': [pos], 'counted': False, 'missed': 0 }) self.next_id += 1 def process_frame(self, frame): """ 处理一帧深度数据并返回检测到的鸡蛋位置 :param frame: 8x8深度矩阵 (单位:mm) :return: (当前检测到的鸡蛋位置, 总计数) """ # 确保frame是二维数组 if frame.ndim == 1: try: frame = frame.reshape(self.grid_size) except ValueError: print(f"无法处理帧数据: {frame.shape}") return [], self.total_count # 1. 更新背景模型 self._update_background(frame) # 2. 前景检测 (鸡蛋深度小于背景) foreground = (self.background - frame) > self.depth_threshold # 3. 聚类检测到的鸡蛋 current_eggs = self._cluster_points(foreground) # 4. 目标跟踪与匹配 self._match_and_track(current_eggs) # 5. 计数逻辑(鸡蛋从右侧离开时计数) for egg in self.tracked_eggs.copy(): # 如果鸡蛋在出口区域且未计数 if not egg['counted'] and egg['pos'][0] >= self.exit_threshold: self.total_count += 1 egg['counted'] = True # 标记为已计数但继续跟踪直到离开视野 # 移出检测区域(右侧太远或宽度方向超出范围) if abs(egg['pos'][1]) > 50 or egg['pos'][0] > 60: self.tracked_eggs.remove(egg) return [egg['pos'] for egg in self.tracked_eggs if not egg['counted']], self.total_count def init_serial(port='COM12', baudrate=115200): """初始化串口连接""" return serial.Serial(port, baudrate, timeout=10) def create_blackwhite_colormap(): """创建黑白渐变色图""" colors = [(0.95, 0.95, 0.95), (0, 0, 0)] # 浅灰到黑 return plt.cm.colors.LinearSegmentedColormap.from_list('bw', colors, N=256) def init_plot(): """初始化深度图显示(传送方向从左到右)""" fig = plt.figure(figsize=(14, 7)) fig.suptitle('VL53L5CX 鸡蛋计数系统(传送方向:左→右)', fontsize=16) # 深度图区域 ax1 = fig.add_subplot(121) cmap = create_blackwhite_colormap() img = ax1.imshow(np.zeros((8,8)), cmap=cmap, vmin=0, vmax=500) plt.colorbar(img, label='距离(mm)', ax=ax1) ax1.set_title('8x8 深度图') ax1.set_xlabel('传送方向(左→右)') ax1.set_ylabel('宽度方向') # 添加传送带表示(红色表示出口) ax1.add_patch(Rectangle([-0.5, -0.5], 8, 8, fill=False, edgecolor='red', linestyle='--')) ax1.text(7.5, 3.5, '→', color='red', fontsize=20, ha='center') # 传送方向箭头 # 鸡蛋位置可视化区域 ax2 = fig.add_subplot(122) ax2.set_xlim(-60, 60) ax2.set_ylim(-60, 60) ax2.set_title('鸡蛋位置检测') ax2.set_xlabel('传送方向(mm) (左→右)') ax2.set_ylabel('宽度方向(mm)') # 添加检测区域和计数线 ax2.add_patch(Rectangle([-50, -50], 100, 100, fill=False, edgecolor='blue')) ax2.axvline(x=30, color='r', linestyle='--', alpha=0.7) # 出口计数线 ax2.text(32, -45, '计数线', color='r', rotation=90) # 添加传送方向箭头 ax2.arrow(-40, 50, 70, 0, head_width=5, head_length=5, fc='r', ec='r') ax2.text(0, 55, '传送方向', color='r', ha='center') # 鸡蛋计数显示 count_text = ax2.text(0, 45, '鸡蛋计数: 0', ha='center', va='center', fontsize=24, color='green', bbox=dict(facecolor='white', alpha=0.8)) # 帧率显示 fps_text = ax2.text(0, -45, 'FPS: 0.0', ha='center', va='center', fontsize=12, color='blue') # 当前跟踪目标显示 track_text = ax2.text(40, -45, '跟踪目标: 0', ha='left', va='center', fontsize=12, color='purple') # 鸡蛋位置点容器 egg_points = ax2.scatter([], [], s=100, c='red', edgecolors='black', alpha=0.7) return fig, img, ax2, count_text, fps_text, track_text, egg_points def update_frame(frame, ser, img, ax, count_text, fps_text, track_text, egg_points, counter, last_time): """更新深度图帧并处理鸡蛋计数(传送方向从左到右)""" current_time = time.time() fps = 1 / (current_time - last_time[0]) if current_time != last_time[0] else 0 last_time[0] = current_time try: # 读取串口数据 data = ser.readline().decode('utf-8').strip() if data: distances = list(map(float, data.split(','))) if len(distances) == 64: depth_map = np.array(distances).reshape(8,8) # 更新深度图显示 img.set_array(depth_map) img.autoscale() # 鸡蛋检测与计数 eggs, total_count = counter.process_frame(depth_map) # 更新鸡蛋位置散点图 if eggs: x_pos = [egg[0] for egg in eggs] y_pos = [egg[1] for egg in eggs] egg_points.set_offsets(np.column_stack([x_pos, y_pos])) else: egg_points.set_offsets([]) # 更新计数显示 count_text.set_text(f'鸡蛋计数: {total_count}') fps_text.set_text(f'FPS: {fps:.1f}') track_text.set_text(f'跟踪目标: {len(counter.tracked_eggs)}') except Exception as e: print(f"Error: {e}") return img, egg_points, count_text, fps_text, track_text def main(): ser = init_serial() counter = EggCounter() fig, img, ax2, count_text, fps_text, track_text, egg_points = init_plot() last_time = [time.time()] ani = animation.FuncAnimation( fig, update_frame, fargs=(ser, img, ax2, count_text, fps_text, track_text, egg_points, counter, last_time), interval=50, blit=True, save_count=1000 ) plt.tight_layout() plt.subplots_adjust(top=0.9) plt.show() ser.close() if __name__ == "__main__": from scipy.optimize import linear_sum_assignment # 确保导入 main()
最新发布
09-12
### Egg Signal Image Recognition Algorithm In the context of egg signal image recognition, algorithms typically involve advanced machine learning techniques to accurately identify and classify eggs within images. While specific studies may not be directly mentioned in provided references, principles from similar domains can offer valuable insights. For instance, when dealing with large datasets containing numerous images, convolutional neural networks (CNNs) are often employed due to their effectiveness in handling complex visual patterns[^1]. CNN architectures excel at feature extraction and classification tasks by leveraging multiple layers designed specifically for spatial hierarchies present in natural scenes or objects like eggs. Moreover, integrating softmax functions into these models ensures proper probability distribution across different classes during prediction phases[^3]: ```python import tensorflow as tf from tensorflow.keras import Sequential from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Softmax model = Sequential([ Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(img_height, img_width, channels)), MaxPooling2D(pool_size=(2, 2)), Flatten(), Dense(units=number_of_classes), Softmax() ]) ``` The theoretical underpinnings behind such intelligent systems also draw upon concepts related to information theory and consciousness modeling efforts aimed at understanding how data processing leads to emergent properties observed in biological organisms[^2].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值