numpy.ndarray如何归一化?
how numpy.ndarray can be normalized?
我正在处理 numpy.ndarray
,包括 286 张形状为 (286, 16, 16, 3)
的图像。每个图像包含 3 个具有不同像素值和 float32 数据类型的波段。每个波段的像素值最大值可以超过255。是否可以将[0-1]之间的numpy.ndarray归一化?
读取图片的代码:
inputPath='E:/Notebooks/data'
images = []
# Load in the images
for filepath in os.listdir(inputPath):
images.append(cv2.imread(inputPath+'/{0}'.format(filepath),flags=(cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)))
如果你想让每张图片的取值范围都在0到255之间,你可以遍历图片,计算原图的最小值和最大值并压缩,所以最小值是0,最大值是255.
import numpy as np
#images = np.random.rand(286,16,16,3)
images = np.random.rand(286,16,16,3).astype(np.float32)
for nr,img in enumerate(images):
min = np.min(img)
max = np.max(img)
# images[nr] = (img - min) * (255/(max-min))
images[nr] = (img - min) / (max - min) * 255
我想通了这段代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Jun 8 13:19:17 2021
@author: Pietro
"""
import numpy as np
arrayz = np.array(np.random.randn(286,16,16,3), dtype=np.float32)
print(arrayz.shape)
print((arrayz.size))
print(arrayz[0,0,0,:],' ',type(arrayz[0,0,0,:]))
print(arrayz[0,0,0,0],' ',type(arrayz[0,0,0,0]))
print(np.min(arrayz),' ',np.max(arrayz))
print(np.min(arrayz),' ',np.max(arrayz))
arrayz_split = np.split(arrayz,286,0)
print(type(arrayz_split))
for i in arrayz_split:
print(i.size,' ', i.shape,' ', np.min(i),' ', np.max(i))
arrayz_split_flat = []
for i in arrayz_split:
ii = i[0]
arrayz_split_flat.append(ii)
for i in arrayz_split_flat:
print(type(i),' ',i.size,' ', i.shape,' ', np.min(i),' ', np.max(i))
arrayz_split_flat_norm = []
for i in arrayz_split_flat:
minz = np.min(i)
manz = np.max(i)
ii = ((i-minz)/(manz-minz)*255).astype(np.uint8)
arrayz_split_flat_norm.append(ii)
for i in arrayz_split_flat_norm:
print(type(i),' ',i.size,' ', i.shape,' ', np.min(i),' ', np.max(i))
out_arr1 = np.stack((arrayz_split_flat_norm), axis = 0)
print(type(out_arr1), out_arr1.size, ' ', out_arr1.shape, ' ',np.min(out_arr1),np.max(out_arr1), out_arr1[0,0,0,:],out_arr1[0,0,0,0])
我不明白为什么:
arrayz = np.array(np.random.randn(286,16,16,3), dtype=np.float32)
似乎在使用时有效:
arrayz1 = np.ndarray((286,16,16,3), dtype="float32")
arrayz = np.nan_to_num(arrayz1)
有效但抛出:
RuntimeWarning: overflow encountered in float_scalars
ii = ((i-minz)/(manz-minz)*255).astype(np.uint8)
RuntimeWarning: invalid value encountered in true_divide
ii = ((i-minz)/(manz-minz)*255).astype(np.uint8)
我最终得到了一系列充满零的 16x16x3 数组
矢量化比迭代快得多
如果您只想使用 numpy
数组缩放所有图像的像素值,您可能希望保持操作的矢量化性质(通过避免循环)。
这是一种缩放图像的方法:
# Getting min and max per image
maxis = images.max(axis=(1,2,3))
minis = images.min(axis=(1,2,3))
# Scaling without any loop
scaled_images = ((images.T - minis) / (maxis - minis) * 255).T
# timeit > 178 µs ± 1.24 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
这里需要转置 .T
才能正确广播减法。
我们可以检查这是否正确:
print((scaled_images.min(axis=(1,2,3)) == 0).all())
# > True
print((scaled_images.max(axis=(1,2,3)) == 255).all())
# > True
缩放到 [0, 1] 范围
如果您想要 0
和 1
之间的像素值,我们只需删除 x255 乘法:
scaled_images = ((images.T - minis) / (maxis - minis)).T
仅适用于 numpy 数组等
您还必须确保首先处理的是 numpy array
,而不是 list
:
import numpy as np
images = np.array(images)
OpenCV
移动缩放
由于您正在使用 opencv
一张一张地读取您的图像,因此您可以随时随地对图像进行标准化:
inputPath='E:/Notebooks/data'
max_scale = 1 # or 255 if needed
# Load in the images
images = [cv2.normalize(
cv2.imread(inputPath+'/{0}'.format(filepath),flags=(cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)),
None, 0, max_scale, cv2.NORM_MINMAX)
for filepath in os.listdir(inputPath)]
确保文件夹中有图片
inputPath='E:/Notebooks/data'
images = []
max_scale = 1 # or 255 if needed
# Load in the images
for filepath in os.listdir(inputPath):
image = cv2.imread(inputPath+'/{0}'.format(filepath),flags=(cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH))
# Scale and append the list if it is an image
if image is not None:
images.append(cv2.normalize(image, None, 0, max_scale, cv2.NORM_MINMAX))
3.4 之前的 open-cv 版本存在错误
据报道 here,opencv 的 normalize
方法产生低于 alpha parameter
的值存在错误。它已在 3.4 版中得到更正。
这是一种使用旧版 open-cv 随时随地缩放图像的方法:
def custom_scale(img, max_scale=1):
mini = img.min()
return (img - mini) / (img.max() - mini) * max_scale
max_scale = 1 # or 255 if needed
images = [custom_scale(
cv2.imread(inputPath+'/{0}'.format(filepath),flags=(cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)), max_scale)
for filepath in os.listdir(inputPath)]
我正在处理 numpy.ndarray
,包括 286 张形状为 (286, 16, 16, 3)
的图像。每个图像包含 3 个具有不同像素值和 float32 数据类型的波段。每个波段的像素值最大值可以超过255。是否可以将[0-1]之间的numpy.ndarray归一化?
读取图片的代码:
inputPath='E:/Notebooks/data'
images = []
# Load in the images
for filepath in os.listdir(inputPath):
images.append(cv2.imread(inputPath+'/{0}'.format(filepath),flags=(cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)))
如果你想让每张图片的取值范围都在0到255之间,你可以遍历图片,计算原图的最小值和最大值并压缩,所以最小值是0,最大值是255.
import numpy as np
#images = np.random.rand(286,16,16,3)
images = np.random.rand(286,16,16,3).astype(np.float32)
for nr,img in enumerate(images):
min = np.min(img)
max = np.max(img)
# images[nr] = (img - min) * (255/(max-min))
images[nr] = (img - min) / (max - min) * 255
我想通了这段代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Jun 8 13:19:17 2021
@author: Pietro
"""
import numpy as np
arrayz = np.array(np.random.randn(286,16,16,3), dtype=np.float32)
print(arrayz.shape)
print((arrayz.size))
print(arrayz[0,0,0,:],' ',type(arrayz[0,0,0,:]))
print(arrayz[0,0,0,0],' ',type(arrayz[0,0,0,0]))
print(np.min(arrayz),' ',np.max(arrayz))
print(np.min(arrayz),' ',np.max(arrayz))
arrayz_split = np.split(arrayz,286,0)
print(type(arrayz_split))
for i in arrayz_split:
print(i.size,' ', i.shape,' ', np.min(i),' ', np.max(i))
arrayz_split_flat = []
for i in arrayz_split:
ii = i[0]
arrayz_split_flat.append(ii)
for i in arrayz_split_flat:
print(type(i),' ',i.size,' ', i.shape,' ', np.min(i),' ', np.max(i))
arrayz_split_flat_norm = []
for i in arrayz_split_flat:
minz = np.min(i)
manz = np.max(i)
ii = ((i-minz)/(manz-minz)*255).astype(np.uint8)
arrayz_split_flat_norm.append(ii)
for i in arrayz_split_flat_norm:
print(type(i),' ',i.size,' ', i.shape,' ', np.min(i),' ', np.max(i))
out_arr1 = np.stack((arrayz_split_flat_norm), axis = 0)
print(type(out_arr1), out_arr1.size, ' ', out_arr1.shape, ' ',np.min(out_arr1),np.max(out_arr1), out_arr1[0,0,0,:],out_arr1[0,0,0,0])
我不明白为什么:
arrayz = np.array(np.random.randn(286,16,16,3), dtype=np.float32)
似乎在使用时有效:
arrayz1 = np.ndarray((286,16,16,3), dtype="float32")
arrayz = np.nan_to_num(arrayz1)
有效但抛出:
RuntimeWarning: overflow encountered in float_scalars
ii = ((i-minz)/(manz-minz)*255).astype(np.uint8)
RuntimeWarning: invalid value encountered in true_divide
ii = ((i-minz)/(manz-minz)*255).astype(np.uint8)
我最终得到了一系列充满零的 16x16x3 数组
矢量化比迭代快得多
如果您只想使用 numpy
数组缩放所有图像的像素值,您可能希望保持操作的矢量化性质(通过避免循环)。
这是一种缩放图像的方法:
# Getting min and max per image
maxis = images.max(axis=(1,2,3))
minis = images.min(axis=(1,2,3))
# Scaling without any loop
scaled_images = ((images.T - minis) / (maxis - minis) * 255).T
# timeit > 178 µs ± 1.24 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
这里需要转置 .T
才能正确广播减法。
我们可以检查这是否正确:
print((scaled_images.min(axis=(1,2,3)) == 0).all())
# > True
print((scaled_images.max(axis=(1,2,3)) == 255).all())
# > True
缩放到 [0, 1] 范围
如果您想要 0
和 1
之间的像素值,我们只需删除 x255 乘法:
scaled_images = ((images.T - minis) / (maxis - minis)).T
仅适用于 numpy 数组等
您还必须确保首先处理的是 numpy array
,而不是 list
:
import numpy as np
images = np.array(images)
OpenCV
移动缩放
由于您正在使用 opencv
一张一张地读取您的图像,因此您可以随时随地对图像进行标准化:
inputPath='E:/Notebooks/data'
max_scale = 1 # or 255 if needed
# Load in the images
images = [cv2.normalize(
cv2.imread(inputPath+'/{0}'.format(filepath),flags=(cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)),
None, 0, max_scale, cv2.NORM_MINMAX)
for filepath in os.listdir(inputPath)]
确保文件夹中有图片
inputPath='E:/Notebooks/data'
images = []
max_scale = 1 # or 255 if needed
# Load in the images
for filepath in os.listdir(inputPath):
image = cv2.imread(inputPath+'/{0}'.format(filepath),flags=(cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH))
# Scale and append the list if it is an image
if image is not None:
images.append(cv2.normalize(image, None, 0, max_scale, cv2.NORM_MINMAX))
3.4 之前的 open-cv 版本存在错误
据报道 here,opencv 的 normalize
方法产生低于 alpha parameter
的值存在错误。它已在 3.4 版中得到更正。
这是一种使用旧版 open-cv 随时随地缩放图像的方法:
def custom_scale(img, max_scale=1):
mini = img.min()
return (img - mini) / (img.max() - mini) * max_scale
max_scale = 1 # or 255 if needed
images = [custom_scale(
cv2.imread(inputPath+'/{0}'.format(filepath),flags=(cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)), max_scale)
for filepath in os.listdir(inputPath)]