Search code examples
arraysjuliaoverlaprectangles

Creating a filled rectangle within an array in Julia


I am new to Julia, and I am trying to understand basic data visualization. I am creating a 2D array of noise with:

xRange, yRange = 1:1:300, 1:1:300
maxVal = 0.3
noiseArr = rand(length(xRange),length(yRange))*maxVal

The resulting array is shown below (left). I would like to identify specific pixels -- defined by a rectangle with length, width, and rotation -- and set those values to a known number. Ultimately, I would like something like the image shown below (right).

I've no package preferences, but I've been looking at Images, OpenCV, etc. I'm hoping there's a straight-forward way to do this.

enter image description here


Solution

  • I would like to identify specific pixels -- defined by a rectangle with length, width, and rotation

    Knowing length, width and rotation is not enough to uniquely position a rectangle on a plane. You also need translation.

    Here is a simple code that gives you an example what you can do (it is not super efficient, but is fast enough for demo purposes):

    function rectangle!(x1, x2, x3, noiseArr, val)
        A = [x2-x1 x3-x1]
        b = x1
        iA = inv(A)
    
        for i in axes(noiseArr, 1), j in axes(noiseArr, 2)
            it, jt = iA * ([i, j]-b)
            0 <= it <= 1 && 0 <= jt <= 1 && (noiseArr[i, j] = val)
        end
    end
    
    x1 = [40, 140]
    x2 = [230, 100]
    x3 = [50, 170]
    rectangle!(x1, x2, x3, noiseArr, 0.0)
    

    In it - instead of passing a rotation, scaling and translation I thought it is easier to assume you pass three vertices of the rectangle x1, x2, and x3 (assuming that its sides are formed by x1-x2 and x1-x3 pairs) and it calculates the affine transformation you need. val is the value the pixels inside of the rectangle should get.

    Note that essentially what we do is computing a reverse affine transformation of a rectangle back to a unit square and check which points lie within a unit square (which is easy).

    (as commenters noted above - this is not an optimal way to do it as you do a lot of computations that are not needed, but I hope that it has the benefit of being easier to understand; also the benefit of Julia is that writing of such a loop is not a problem and it still runs fast enough)