Search code examples
halide

Programming a dynamic box blur


I tried making function that generates the expression for the box blur whose matrix's size can be either 3,5 or 7 and while the program does call the function it always returns a static number which I put as a definition of the Expr object. So basically it's like it doesn't do the for loop. Any tips would be greatly appreciated as I'm very new to Halide and image processing in general.

function that creates the Expr:

Halide::Expr calculateBlur(Halide::Image<uint8_t> input, Halide::Var x, Halide::Var y, Halide::Var c, float* matrix, int size) {
    Halide::Expr endResult = Halide::cast<float>(120.0f);
    float endRes = 0.0f;
    int xPointer = 0;
    int yPointer = 0;
    int squareRootofSize = sqrt(size);
    for (int i = 0; i < size; i++) {    
        endResult = Halide::operator+(endResult, Halide::cast<float>((x - ((squareRootofSize / 2)) + xPointer, y - ((squareRootofSize / 2)) + yPointer, c) * (1/size)));                    
        xPointer++;
        if ((i + 1) % squareRootofSize == 0) {              
            yPointer++;
            xPointer = 0;
        }
    }
    endResult = Halide::cast<uint8_t>(endResult);
    return endResult;
}

blur function:

void blur2(Halide::Image<uint8_t> input, float* matrix, int size) {
    Halide::Var x, y, c;
    myBlurFunction(x, y, c) = calculateBlur(input, x, y, c, matrix, size);/
    for (int i = 0; i < size / 2; i++) { //creates a border
        myBlurFunction(x, 0+i, c) = Halide::cast<uint8_t>(0);
        myBlurFunction(0 + i, y, c) = Halide::cast<uint8_t>(0);
        myBlurFunction(input.width() - 1 - i, y, c) = Halide::cast<uint8_t>(0);
        myBlurFunction(x, input.height() - 1 - i, c) = Halide::cast<uint8_t>(0);
    }
    Halide::Image<uint8_t> output;
    output = myBlurFunction.realize(input.width(), input.height(), input.channels());
    Halide::Tools::save_image(output, "C:\\Users\\Admin\\Desktop\\rgb\\boxBlurColor.png");`
}

Also I do have some prints for testing and the text from the calculateBlur function only appears once. I also used trace_stores() which confirmed that all output values were set on 0.0f.

UPDATE: I replaced the line in the calculateBlur

endResult = Halide::operator+(endResult, Halide::cast<float>((x - ((squareRootofSize / 2)) + xPointer, y - ((squareRootofSize / 2)) + yPointer, c) * (1/size)));

with

endResult = Halide::operator+(endResult, input((x - ((squareRootofSize / 2)) + xPointer, y - ((squareRootofSize / 2)) + yPointer, c)) * (1/size));

and now i'm getting the following error: "Can't construct a 1-argument reference to Image "i0" with 3 dimensions."

UPDATE2:

after further modifying the line in the calculateBlur from

endResult = Halide::operator+(endResult, input((x - ((squareRootofSize / 2)) + xPointer, y - ((squareRootofSize / 2)) + yPointer, c)) * (1/size));

to

Halide::operator+=(endResult, (input((x - ((squareRootofSize / 2)) + xPointer), (y - ((squareRootofSize / 2)) + yPointer), c) * (1/squareRootofSize)));

I'm getting the following error: "Input buffer i0 is accessed at -2, which is before the min(0) in dimension 0" which I don't understand why it's appearing since i did redefine function for borders and corners

UPDATE3:

I realized that the error kept popping up because if i realize the function with it starting at 0,0 the function i made will throw the exception. So now my question is: Can I make a border around the picture so the result would retain it's dimensions without the program throwing an exception? Also the result doesn't seem to be blurred at all.


Solution

  • For the last asked question, take a look at the boundary conditions For the first, at Halide compile time the loop count is known so it can optimize the loop away (I suspect, I want to stress I do not know this).