NumPy将8位图像转换为16/32位图像

6 投票
2 回答
22866 浏览
提问于 2025-04-18 11:17

我正在使用OpenCV 2对YCbCr颜色空间中的一些图像进行处理。目前,我可以检测到由于RGB转换为YCbCr,然后再转换回RGB时产生的一些噪声。不过,正如文档中所说:

如果你使用cvtColor处理8位图像,转换过程中会丢失一些信息。对于很多应用来说,这种损失可能不明显,但如果你的应用需要完整的颜色范围,或者在进行某些操作之前转换图像,然后再转换回来,建议使用32位图像。

所以我想把我的图像转换成16位或32位的,但我没有找到如何用NumPy做到这一点。有没有什么想法?

img = cv2.imread(imgNameIn)
# Here I want to convert img in 32 bits
cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB, img)
# Some image processing ...
cv2.cvtColor(img, cv2.COLOR_YCR_CB2BGR, img)
cv2.imwrite(imgNameOut, img, [cv2.cv.CV_IMWRITE_PNG_COMPRESSION, 0])

2 个回答

0

这个被接受的答案不太准确。一个16位的图像有65536个亮度级别(2^16),所以它的数值范围是从065535

如果你想把一个表示为从0到1的float数组的图像转换成16位图像,你需要把这个数组里的每个值都乘以65535

另外,最后一步操作时把结果的类型转换成你想要的类型是个好习惯。这主要有两个原因: - 如果你在计算中进行了除法或乘法运算,结果会是float类型,这样你还得再转换一次。 - 一般来说(从数学的角度来看),从浮点数转换成整数可能会引入误差。在所有操作结束后再进行类型转换,可以避免误差的传播。

3

感谢@moarningsun,问题已经解决:

i = cv2.imread(imgNameIn, cv2.CV_LOAD_IMAGE_COLOR) # Need to be sure to have a 8-bit input
img = np.array(i, dtype=np.uint16) # This line only change the type, not values
img *= 256 # Now we get the good values in 16 bit format

撰写回答