我正在将TangoImageBuffer.data指向的整个缓冲区写入文件。
// open a file
std::fstream f(app.getNextFileName(), std::ios::out | std::ios::binary);
// write the entire stride * height * 4 buffer into the file
f.write((const char *) tango_image_buffer->data,
tango_image_buffer->stride * buffer->height * 4 * sizeof(uint8_t)
);
f.close();
然后我将文件导出到我的PC并使用python-opencv和numpy进行可视化:
import sys
import cv2
import numpy as np
# dimensions of the image
stride = 1280
width = 1280
height = 720
# I am using 3 channels so that the resulting image is not
# transluscent
channels = 3
input_filename = sys.argv[1]
output_filename = sys.argv[2]
# load the image buffer into a list
data = np.fromfile(input_filename, dtype=np.uint8)
# create a height x width x channels matrix with the datatype uint8
# and all elements set to zero
img = np.zeros((height, width, channels), dtype=np.uint8);
# map elements in array to image matrix
for y in range(0, height):
for x in range(0, width):
img[y, x, 0] = data[y * stride + x + 2] #blue
img[y, x, 1] = data[y * stride + x + 1] #green
img[y, x, 2] = data[y * stride + x + 0] #red
# display and save the resulting image
cv2.namedWindow("tango-rgba")
cv2.imshow("tango-rgba", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite(output_filename, img)
不幸的是,生成的图片looks gray
仅图像为灰色。仔细检查像素后,您会发现像素的红色,绿色和蓝色成分为different。
编辑:我已更改此帖子以指定我使用的缓冲区是RGBA8888格式。从Project Tango Reference,"仅提供RGBA 8888"
编辑:实际上似乎没有使用RGBA8888格式。 rhashimoto建议格式为YV12。
编辑:图像格式实际上是NV21(见下面的答案)。
答案 0 :(得分:3)
似乎在写这篇文章时,Project Tango Reference确实是不正确的。
图像格式为NV21。
char format_str[100] = {0};
switch (tango_image_buffer->format)
{
case TANGO_HAL_PIXEL_FORMAT_RGBA_8888:
sprintf(format_str, "%s", "RGBA8888");
break;
case TANGO_HAL_PIXEL_FORMAT_YV12:
sprintf(format_str, "%s", "YV12");
break;
case TANGO_HAL_PIXEL_FORMAT_YCrCb_420_SP:
sprintf(format_str, "%s", "NV21");
break;
default:
break;
}
__android_log_print(ANDROID_LOG_VERBOSE, "Capture Info",
"stride: %u, width: %u, height: %u, timestamp: %lf, frame: %llu, format: %s",
tango_image_buffer->stride,
tango_image_buffer->width,
tango_image_buffer->height,
tango_image_buffer->timestamp,
tango_image_buffer->frame_number,
format_str);
上面一段代码的输出是:
V/Capture Info﹕ stride: 1280, width: 1280, height: 720, timestamp: 22157.368703, frame: 0, format: NV21
这是我在python中使用opencv和numpy的新可视化代码:
import sys
import cv2
import numpy as np
input_filename = sys.argv[1]
output_filename = sys.argv[2]
# dimensions of the image
stride = 1280
width = 1280
height = 720
channels = 4
# load file into buffer
data = np.fromfile(input_filename, dtype=np.uint8)
# create yuv image
yuv = np.ndarray((height + height / 2, width), dtype=np.uint8, buffer=data)
# create a height x width x channels matrix with the datatype uint8 for rgb image
img = np.zeros((height, width, channels), dtype=np.uint8);
# convert yuv image to rgb image
cv2.cvtColor(yuv, cv2.COLOR_YUV2BGRA_NV21, img, channels)
# display and save the resulting image
cv2.namedWindow("tango-rgba")
cv2.imshow("tango-rgba", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite(output_filename, img)
TLDR:图像格式为NV21。 OpenCV提供将NV21转换为RGB的功能。 result看起来很棒。