【发布时间】:2024-04-22 09:10:01
【问题描述】:
我有一个不适合内存的巨大图像数据集。我想计算mean 和standard deviation,从磁盘加载图像。
我目前正在尝试使用在 wikipedia 上找到的算法。
# for a new value newValue, compute the new count, new mean, the new M2.
# mean accumulates the mean of the entire dataset
# M2 aggregates the squared distance from the mean
# count aggregates the amount of samples seen so far
def update(existingAggregate, newValue):
(count, mean, M2) = existingAggregate
count = count + 1
delta = newValue - mean
mean = mean + delta / count
delta2 = newValue - mean
M2 = M2 + delta * delta2
return existingAggregate
# retrieve the mean and variance from an aggregate
def finalize(existingAggregate):
(count, mean, M2) = existingAggregate
(mean, variance) = (mean, M2/(count - 1))
if count < 2:
return float('nan')
else:
return (mean, variance)
这是我当前的实现(只为红色通道计算):
count = 0
mean = 0
delta = 0
delta2 = 0
M2 = 0
for i, file in enumerate(tqdm(first)):
image = cv2.imread(file)
for i in range(224):
for j in range(224):
r, g, b = image[i, j, :]
newValue = r
count = count + 1
delta = newValue - mean
mean = mean + delta / count
delta2 = newValue - mean
M2 = M2 + delta * delta2
print('first mean', mean)
print('first std', np.sqrt(M2 / (count - 1)))
这个实现在我尝试过的数据集的一个子集上运行得足够接近。
问题是它非常慢,因此无法生存。
有标准的方法吗?
如何调整它以获得更快的结果或计算所有数据集的 RGB 均值和标准差,而无需同时以合理的速度将其全部加载到内存中?
【问题讨论】:
-
Olla Bruno...听起来多处理是您的解决方案。最后,您需要将每个图像加载到内存中......最终......但是通过多进程,您可以拆分工作负载并将文件列表拆分为可以更轻松地处理的块,因此不会完全耗尽您的内存.使用 thread1 设置进程,然后在 4-7 个内核上每单位时间分出(取决于您的内核)4-7 个线程进程。如果处理速度很快,您可以将每个核心发送的线程数加倍。想想线程中的python示例...ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer.
标签: python opencv computer-vision