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

6
我正在使用OpenCV2在YCbCr色域中进行一些图像处理。目前我可以检测到由于RGB -> YCbCr转换以及YCbCr -> RGB转换引起的一些噪点,但如文档中所述:
如果您使用8位图像进行cvtColor,则会丢失某些信息。对于许多应用程序,这可能不会被注意到,但建议在需要完整颜色范围或在操作之前转换图像然后再次转换的应用程序中使用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])

1
有提示请参见 https://dev59.com/71_Va4cB1Zd3GeqPU5gi - user2379410
如果它解决了你的问题,请将其作为答案编写并接受,以便将其标记为“已解决”。 - Abid Rahman K
抱歉,我没有看到任何接受答案并将问题标记为已解决的按钮,我该怎么做? - Appukuttan
@user3263033 你需要发布一个回答来回答你的问题,然后点击你的回答旁边的勾选标记以接受它。 - ali_m
2个回答

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

0
接受的答案不准确。16位图像具有65536个强度级(2^16),因此值范围从065535
如果想要从表示为介于0到1之间的float数组的图像中获得16位图像,则必须将该数组的每个系数乘以65535
此外,将您执行的操作的类型转换为最后一步是很好的做法。 这主要是出于两个原因: - 如果通过float执行除法或乘法,则结果将返回一个float,您需要再次更改类型。 - 通常(在数学上的意义上),从浮点数到整数的转换可能会引入误差。 在操作的最后一步进行类型转换可以防止错误传播。

1
“乘法的结果通常返回一个浮点数”-- 你能否提供一些这种情况发生的演示呢? - Dan Mašek
@DanMašek 我所说的“一般”是数学上的意义——至少一次。我重新用更清晰的方式表达了我的想法。感谢您指出我的回答令人困惑。 - Eskapp
1
你也可以使用 cv2.normalize(img, dst=None, alpha=0, beta=65535, norm_type=cv2.NORM_MINMAX) 来获取正确的16位值。 - skull3r7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接