咨询将形状(39000,64,64,3)的ndarray转为灰度图的正确方法
Let's break down why your current code isn't working and get it sorted out properly.
The Core Issue with Your Code
Your while loop is overwriting gray_dataset every iteration—each time you process an image, you replace the entire variable with just that single grayscale result. By the end of the loop, you only have the last image's grayscale version instead of all 39,000. That's exactly why your output doesn't match what you expected.
Solution 1: Fix the Loop with Preallocated Array
For large datasets like yours, preallocating a numpy array is the most efficient approach. It avoids dynamic memory overhead and keeps your data organized from the start:
import numpy as np # Assume your original dataset is shaped (39000, 64, 64, 3) with dtype uint8 num_images, height, width, _ = dataset.shape # Preallocate the result array to match the desired output shape gray_dataset = np.zeros((num_images, height, width), dtype=np.uint8) image_index = 0 while image_index < num_images: # Calculate grayscale values using the standard luminance formula gray_vals = np.dot(dataset[image_index, :, :], [0.299, 0.587, 0.114]) # Round and convert back to uint8 (since dot returns floating-point values) gray_dataset[image_index] = np.round(gray_vals).astype(np.uint8) image_index += 1
Solution 2: Collect Results in a List (Simpler Alternative)
If you prefer not to preallocate upfront, you can collect each grayscale image in a list first, then convert it to a numpy array at the end:
import numpy as np gray_list = [] image_index = 0 num_images = dataset.shape[0] while image_index < num_images: gray_vals = np.dot(dataset[image_index, :, :], [0.299, 0.587, 0.114]) gray_list.append(np.round(gray_vals).astype(np.uint8)) image_index += 1 # Convert the list of images to a single numpy array gray_dataset = np.array(gray_list)
Bonus: Super Fast Vectorized Operation (No Loop Needed!)
Numpy is built for vectorized operations—you can convert all 39,000 images to grayscale in one line, no loops required. This is drastically faster than a while loop, especially for large datasets:
import numpy as np # Perform dot product across the color channel axis (axis=3) for all images gray_dataset = np.dot(dataset, [0.299, 0.587, 0.114]) # Convert back to uint8 to match your original input dtype (optional but recommended) gray_dataset = np.round(gray_dataset).astype(np.uint8)
Numpy automatically handles the dot product across the last dimension (your RGB channels) for every image, directly giving you a (39000, 64, 64) array.
Quick Notes
- The formula
0.299*R + 0.587*G + 0.114*Bis the industry standard for RGB-to-grayscale conversion, as it accounts for human perception of brightness. - Converting back to
uint8ensures your grayscale data matches the original input's range (0-255) and data type.
内容的提问来源于stack exchange,提问作者KingVidfamne

