openimageio - OpenImageIO:以显示窗口分辨率而不是数据分辨率打开图像
问题描述
我正在使用 OpenImage Denoiser,它使用 OpenImageIO 加载 EXR 文件。
图像加载如下:
std::shared_ptr<ImageBuffer> loadImageOIIO(const std::string& filename, int channels)
{
auto in = OIIO::ImageInput::open(filename);
if (!in)
throw std::runtime_error("cannot open image file: " + filename);
const OIIO::ImageSpec& spec = in->spec();
if (channels == 0)
channels = spec.nchannels;
else if (spec.nchannels < channels)
throw std::runtime_error("not enough image channels");
auto image = std::make_shared<ImageBuffer>(spec.width, spec.height, channels);
if (!in->read_image(0, 0, 0, channels, OIIO::TypeDesc::FLOAT, image->getData()))
throw std::runtime_error("failed to read image data");
in->close();
#if OIIO_VERSION < 10903
OIIO::ImageInput::destroy(in);
#endif
return image;
}
但是,这会将图像裁剪到数据窗口的边界框。因为我的图像有 0 个值,所以这个图像比实际输入的图像小。
如何获得具有显示窗口全分辨率的 ImageBuffer?
解决方案
上面的行是分配一个宽 x 高 x 通道的图像,但问题是从 OIIO 的角度来看,spec.width 和 height 描述了数据窗口。所以你想从
auto image = std::make_shared<ImageBuffer>(spec.full_width, spec.full_height, channels);
这为“完整”(显示)窗口分配了一个缓冲区。
然后,您想使用您保留为默认值的一些附加参数调用 read_image,这些参数可让您显式跨步。如果没有跨步,它假定您正在读取一个连续的缓冲区,并且大小正好适合数据窗口。提供步幅会将像素偏移写入具有正确间距的正确位置,并且您还希望正确偏移到缓冲区中。我想你想要这个:
size_t pixelsize = channels * sizeof(float);
size_t scanlinesize = pixelsize * spec.full_width;
if (!in->read_image(/*subimage*/ 0, /*miplevel*/ 0, /*chbegin*/ 0, /*chend*/ channels,
OIIO::TypeDesc::FLOAT,
image->getData() + spec.x * pixelsize + spec.y * scanlinesize,
/*xstride*/ pixelsize, /*ystride*/ scanlinesize)
不要忘记先将缓冲区归零,因为现在 read_image 调用不会覆盖所有缓冲区值,只会覆盖具有数据像素的值!
现在,即使这也不是很普遍。我通过假设您的显示窗口(OIIO 称为“完整”)的原点为 (0,0) 并且与没有黑色像素的图像的数据窗口相同 - 即数据和完整仅因为“裁剪”到非零区域而有所不同。但实际上,有可能(并且在生产中经常出现)具有大于显示窗口的数据窗口,这意味着您正在计算“过扫描”区域(包括让数据窗口可能扩展到负像素索引)。如果可能是这种情况,并且您需要覆盖所有可能的基础,那么您可能需要分配一个图像,该图像是显示窗口和数据窗口之间重叠的联合,并调整上面的代码以正确处理此问题。
推荐阅读
- windows - 递归批量搜索所有目录中的字符串
- javascript - 我怎样才能在这个向上滑动的面板中制作动画并且仍然保持可拖动范围?
- python - Python:停止列表在输入时将两位数分开
- javascript - 我在 d3 中使用 scaleTime() 函数输入日期的方式有什么问题?
- react-native - 在 react-native 中发布后如何获取?
- angular - 刷新另一个页面时,角度路由重定向到主页
- php - twak 代码未在 php 中给出响应并发出通知未定义索引:HTTP_X_TAWK_SIGNATURE 和此未定义变量:rawPost
- python - Python - Flask ImportError:无法从“模型”导入名称“Userauth”
- curl - 使用 HTTP 请求 CouchDB 3.0.0 检索文档
- javascript - 尽可能多地重新加载 iframe 并单击 iframe 内的按钮