【发布时间】:2021-07-16 04:10:50
【问题描述】:
我想在 Javascript 中加载一个 16 位灰度 PNG(其中每个像素代表一个数字/深度值。This is file format is used by TUM to store depth information)
但是,opencv.js 读取的图像是 RGBA 8bits (mat.type() == 24 == cv.CV_8UC4 - 我想得到cv.CV_16UC1),这似乎是因为图像是由浏览器本身解码的,Because canvas only support 8-bit RGBA image with continuous storage, the cv.Mat type is cv.CV_8UC4 作为documentation 表示它。因此,我们没有得到一个像素,而是得到一个介于 0 和 65535 (2^8-1) 之间的值,而是得到一个介于 0 和 255 (2^8-1) 之间的数字,其中 R=G=B 和 A=255
[编辑] 为了重新制定它,画布将我的 16 位灰度转换为 8 位 RGBA。画布处理 2^24 种颜色,但在转换过程中 R=G=B 并且每个通道是 2^8,因此它只处理 2^8 灰度而不是 2^16 灰度。
没有做任何特别的事情: https://jsfiddle.net/remmel/rmntq4yb/74/
摘录:
var img = await loadImage("https://raw.githubusercontent.com/remmel/rgbd-dataset/main/rgbd_dataset_freiburg1_desk/depth/1305031468.188327.png");
var canvasOriginal = document.getElementById('canvas0')
var ctxOriginal = canvasOriginal.getContext('2d')
canvasOriginal.width = img.width
canvasOriginal.height = img.height
ctxOriginal.drawImage(img, 0, 0)
var mat = cv.imread('canvas0')
console.log(mat.channels(), mat.type() === cv.CV_8UC4) //4, true
图像魔术:
$ identify 1305031468.188327.png
1305031468.188327.png PNG 640x480 640x480+0+0 16-bit Grayscale Gray 131604B 0.000u 0:00.000
我尝试使用 jimp-browser 解码图像,但仍然得到 RGBA 图像。调试它,我看到它在 16 位中读取了正确的灰度值,但在将其转换为 8 位后,R=G=B=gray 8bit 和 A=255。一个解决方案可能是自定义 (fix?) 该库
我也尝试使用 OpenCV.js 直接加载图像,但仍然是相同的 4 通道图像:
<img src='https://i.stack.imgur.com/8am9t.png' id='dpng' />
var depthMat2 = cv.imread('dpng')
console.log(depthMat2.channels(), depthMat2.type() === cv.CV_8UC4) //4 true
【问题讨论】:
-
我不明白这个问题。画布支持 16,777,216 种颜色。你的实际目标是什么?
-
是的,画布支持 2^24 颜色。但它似乎只支持 256 个灰度。 Canvas 将 16 位灰度图像转换为 8 位 RGBA
-
实际有 256 种灰色,因为灰色是指 RGB 光谱的所有颜色都相同。 R = 0,G = 0,B = 0; R = 1,G = 1,B = 1;一直到 R = 255,G = 255,B = 255。
-
是的,但我的原始图像的灰度介于 0 和 65535 之间。并且 Canvas 无法处理 R=65535、G=65535、B=65535(如果有帮助,我进行了编辑)跨度>
-
Canvas
ctx.drawImage(imageElement)应该会自动工作,只要该 imageElement 已加载并且是.png。我还是不明白你的目的。这是什么?
标签: javascript opencv