Reputation: 1795
I want to load a 16 bit grayscale PNG in Javascript (where each pixel represent a number/depth value. This is file format is used by TUM to store depth information)
However, the image read by opencv.js is RGBA 8bits (mat.type() == 24 == cv.CV_8UC4
- and I would like to get cv.CV_16UC1
), which seems to be because the image is decode by the browser itself and Because canvas only support 8-bit RGBA image with continuous storage, the cv.Mat type is cv.CV_8UC4
as the documentation indicates it. Thus instead of getting a pixel we a value between 0 and 65535 (2^8-1) I get a number between 0 and 255 (2^8-1) with R=G=B and A=255
[Edit] To reformulate it, canvas convert my 16bit grayscale to 8bit RGBA. Canvas handle 2^24 colors but as during the conversion R=G=B and each channel is 2^8, thus it handle only 2^8 grays instead of 2^16 grays.
Nothing special is done : https://jsfiddle.net/remmel/rmntq4yb/74/
Extract:
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
Image magick:
$ identify 1305031468.188327.png
1305031468.188327.png PNG 640x480 640x480+0+0 16-bit Grayscale Gray 131604B 0.000u 0:00.000
I tried to decoded the image using jimp-browser, but still get a RGBA image. Debugging it, I see that it read the correct gray value in 16bit but after convert it in 8bit with R=G=B=gray 8bit and A=255. A solution could be to custom (fix?) that lib
I also tried loading directly the image with OpenCV.js, but still the same 4 channels image :
<img src='https://i.sstatic.net/8am9t.png' id='dpng' />
var depthMat2 = cv.imread('dpng')
console.log(depthMat2.channels(), depthMat2.type() === cv.CV_8UC4) //4 true
Image (imgur seems to not compress the image) :
Upvotes: 2
Views: 1388
Reputation: 1795
I used instead fast-png
lib to read my 16 bits grayscale PNG : https://www.npmjs.com/package/fast-png
import { decode } from 'fast-png'
...
var arrayBuffer = await((await fetch(urlDepth)).arrayBuffer())
var depthData = (await decode(arrayBuffer)).data
Upvotes: 2
Reputation: 10627
I think you just want to do ratio math:
function rgbAlter(rgb){
return 65535/255*rgb;
}
for(let i=0,l=256; i<l; i++){
console.log(rgbAlter(i));
}
Upvotes: -2