这是我在这里的第一篇文章,对不起,如果我做错了:)。我会尽力而为。
我目前正在研究HDR图像处理程序,并且我打算使用Halide实现一些基于TMO的功能。问题是我所有的图像都表示为float数组(顺序为:b1,g1,r1,a1,b2,g2,r2,a2,...)。使用Halide处理图像需要Halide :: Image类。问题是我不知道如何将那些数据传递到那里。
任何人都可以提供帮助,或者有相同的问题并且知道答案吗?
编辑:
终于明白了!我需要在生成器的输入和输出缓冲区上设置跨度。感谢所有帮助:-)
编辑:
我尝试了两种不同的方法:
int halideOperations( float data[] , int size, int width,int heighy )
{
buffer_t input_buf = { 0 };
input_buf.host = &data[0];
}
要么:
int halideOperations( float data[] , int size, int width,int heighy )
{
Halide::Image(Halide::Type::Float, x, y, 0, 0, data);
}
我当时正在考虑编辑Halide.h文件并将uint8_t * host更改为float_t * host,但是我认为这不是个好主意。
编辑:
我尝试在浮动图片(RGBA)中使用以下代码:
AOT函数生成:
int main(int arg, char ** argv)
{
Halide::ImageParam img(Halide::type_of<float>(), 3);
Halide::Func f;
Halide::Var x, y, c;
f(x, y, c) = Halide::pow(img(x,y,c), 2.f);
std::vector<Halide::Argument> arguments = { img };
f.compile_to_file("function", arguments);
return 0;
}
正确的代码调用:
int halideOperations(float data[], int size, int width, int height)
{
buffer_t output_buf = { 0 };
buffer_t buf = { 0 };
buf.host = (uint8_t *)data;
float * output = new float[width * height * 4];
output_buf.host = (uint8_t*)(output);
output_buf.extent[0] = buf.extent[0] = width;
output_buf.extent[1] = buf.extent[1] = height;
output_buf.extent[2] = buf.extent[2] = 4;
output_buf.stride[0] = buf.stride[0] = 4;
output_buf.stride[1] = buf.stride[1] = width * 4;
output_buf.elem_size = buf.elem_size = sizeof(float);
function(&buf, &output_buf);
delete output;
return 1;
}
不幸的是,我崩溃了味精:
Error: Constraint violated: f0.stride.0 (4) == 1 (1)
我认为这行有问题:output_buf.stride [0] = buf.stride [0] = 4,但我不确定应该更改什么。有小费吗?
最佳答案
如果直接使用buffer_t,则必须将分配给host的指针强制转换为uint8_t *:
buf.host = (uint8_t *)&data[0]; // Often, can be just "(uint8_t *)data"
如果使用的是Ahead-Of-Time(AOT)编译,而数据没有作为直接调用Halide的代码的一部分进行分配,这就是您要执行的操作。 (下面讨论的其他方法控制着存储分配,因此它们不能采用传递给它们的指针。)
如果您使用Halide :: Image或Halide :: Tools :: Image,则类型转换在内部进行处理。上面用于Halide :: Image的构造函数不存在,因为Halide :: Image是模板类,而基础数据类型是模板参数:
Halide::Image<float> image_storage(width, height, channels);
请注意,这会将数据存储在平面布局中。 Halide :: Tools :: Image相似,但是可以选择交错布局。 (就个人而言,我尽量不要在小型测试程序中使用这两种方法。有一个长期计划来合理化所有这些方法,这些方法将在合并任意维buffer_t分支后继续进行。请注意,Halide :: Image需要libHalide.a链接到Halide :: Tools :: Image没有的地方,并且仅通过包含common / halide_image.h才是头文件。)
还有Halide :: Buffer类,它是buffer_t的包装,在即时(JIT)编译中很有用。它可以引用存储中传递的内容,并且不进行模板化。但是我的猜测是您想直接使用buffer_t,只需要类型转换就可以分配主机。另外,请确保将buffer_t的elem_size字段设置为“ sizeof(float)”。
对于交错浮点缓冲区,您将得到类似以下内容的结果:
buffer_t buf = {0};
buf.host = (uint8_t *)float_data; // Might also need const_cast
// If the buffer doesn't start at (0, 0), then assign mins
buf.extent[0] = width; // In elements, not bytes
buf.extent[1] = height; // In elements, not bytes
buf.extent[2] = 3; // Assuming RGB
// No need to assign additional extents as they were init'ed to zero above
buf.stride[0] = 3; // RGB interleaved
buf.stride[1] = width * 3; // Assuming no line padding
buf.stride[2] = 1; // Channel interleaved
buf.elem_size = sizeof(float);
您还需要注意Halide代码本身的界限。可能最好查看tutorial / lesson_16_rgb_generate.cpp中的set_stride和bound调用以获取有关此信息。
关于c++ - 将 Halide 与以浮点数组表示的HDR图像一起使用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36822003/