2016-04-24 43 views
0

這是我的第一篇文章,所以對不起,如果我做錯了什麼:)。我會盡力做到最好。使用鹵素與HDR圖像表示爲浮法陣列

我目前正在研究HDR圖像處理程序,並且我使用Halide實現了一些基礎TMO。問題是我所有的圖像被表示爲浮點數組(例如:b1,g1,r1,a1,b2,g2,r2,a2,...)。使用Halide處理圖像需要使用Halide :: Image類。問題是我不知道如何在那裏傳遞這些數據。

任何人都可以幫忙,或有同樣的問題,並知道答案?

編輯:

終於明白了!我需要在發生器中設置輸入和輸出緩衝區的大小。 THX所有的幫助:-)

編輯:

我嘗試兩種不同的方式:

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 *主機float_t *主機,但我不認爲這是個好主意。

編輯:

我嘗試使用下面的代碼與我的浮動圖像(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; 
} 

不幸我碰到了msg:

Error: Constraint violated: f0.stride.0 (4) == 1 (1) 

我覺得這行有一些錯誤:output_buf.stride [0] = buf.stride [0] = 4,但我不確定應該改變什麼。有小費嗎?

+0

嗨,歡迎!你能告訴我們你試過的代碼嗎? – rhughes

+0

我試圖使用buffer_t和正常的Halide :: Image,但它們都使用uint8而不是float數據:int halideOperations(float data [],int size,int x,int y) \t \t \t buffer_t input_buf = {0 }; \t \t input_buf.host =&data [0]; } or: \t \t Halide :: Image(Halide :: Type :: Float,x,y,0,0,data); –

+0

謝謝。你可以編輯你的問題給我們看你的代碼嗎? – rhughes

回答

1

如果您是直接使用buffer_t,必須轉換分配給主機的指針uint8_t *:

buf.host = (uint8_t *)&data[0]; // Often, can be just "(uint8_t *)data" 

這是你想要的,如果你使用的是名列前茅的時間做什麼(AOT)編譯和數據不作爲直接調用Halide的代碼的一部分進行分配。 (下面討論的其他方法控制存儲分配,因此它們不能接受傳遞給它們的指針)。

如果您使用Halide :: Image或Halide :: Tools :: 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類這是在實時(JIT)編譯中有用的buffer_t上的一個包裝器。它可以引用通過存儲並且不是模板化的。不過,我的猜測是你想直接使用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); 

您還需要注意的邊界在鹵化物代碼本身:

對於交錯float緩衝區,你會喜歡的東西而告終。可能最好查看tutorial/lesson_16_rgb_generate.cpp中的set_stride和綁定調用以獲取有關該信息的信息。

0

除了Zalman的回答上面,你也必須定義你的金滷燈功能像下面當輸入和輸出指定的進步:

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); 

    // You need the following 
    f.set_stride(0, f.output_buffer().extent(2)); 
    f.set_stride(1, f.output_buffer().extent(0) * f.output_buffer().extent(2)); 
    img.set_stride(0, img.extent(2)); 
    img.set_stride(1, img.extent(2) *img.extent(0)); 
    // <- up to here 

    std::vector<Halide::Argument> arguments = { img }; 
    f.compile_to_file("function", arguments); 
    return 0; 
} 

那麼你的代碼應該運行。