如何使用Python和OpenCV创建5位每像素图像及实现8位每像素RGB图像到5位每像素图像的转换
Hey there! Let's walk through how to convert that 8-bit per channel RGB image to 5-bit using Python and OpenCV. It's simpler than it sounds once you get the scaling logic down.
First, a quick refresher: An 8-bit color channel gives values ranging from 0 to 255, while a 5-bit channel only needs values from 0 to 31 (since 2^5 = 32). Our goal is to map the larger 8-bit range down to the smaller 5-bit range, then store those values (we'll still use 8-bit uint8 arrays for compatibility with OpenCV—we just limit the values to 0-31).
Two Practical Conversion Methods
Method 1: Linear Scaling (Precise)
This method scales each pixel value proportionally from the 8-bit range to the 5-bit range, preserving as much relative brightness as possible.
import cv2 import numpy as np # Load your 8-bit RGB image (OpenCV reads in BGR format by default) img = cv2.imread("your_input_image.png", cv2.IMREAD_COLOR) # Scale each channel from 0-255 to 0-31, then convert back to uint8 five_bit_img = (img / 255.0 * 31).astype(np.uint8) # Save the converted image cv2.imwrite("5bit_output.png", five_bit_img) # Optional: Display the result cv2.imshow("5-bit Image", five_bit_img) cv2.waitKey(0) cv2.destroyAllWindows()
Method 2: Bit Shifting (Fast)
If speed is a priority, bit shifting is a more efficient integer-based operation. Since 255 >> 3 = 31, shifting each 8-bit value right by 3 bits discards the least significant 3 bits, leaving the top 5 bits (which exactly map to 0-31).
import cv2 import numpy as np img = cv2.imread("your_input_image.png", cv2.IMREAD_COLOR) # Right-shift each channel by 3 bits to get 5-bit equivalent values five_bit_img = img >> 3 # Save or display the result cv2.imwrite("5bit_output_fast.png", five_bit_img)
Key Tips to Keep in Mind
- Color Order: OpenCV reads images in BGR format, but the conversion logic works the same regardless of RGB/BGR order. If you need RGB for other processing, just add
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)after loading the image. - Storage Note: Even though we're working with 5-bit values, we store them in 8-bit
uint8arrays because OpenCV doesn't natively support 5-bit image formats. The values will simply stay within the 0-31 range instead of 0-255. - Restoring for Display: If you want to view the 5-bit image at full brightness, you can scale it back to 8-bit by left-shifting 3 bits (
five_bit_img << 3) or using linear scaling again ((five_bit_img / 31.0 * 255).astype(np.uint8)).
内容的提问来源于stack exchange,提问作者Philip

