OpenCV4Nodejs – Draw a grid over an image

A lot of my work is going to be porting my Python work over the years to OpenCV4Nodejs.  I have some Java and C++ (even some C#) in OpenCV, but mostly Python work.  I’ve been horrible at documenting my work except in handwritten scribbles or bookmarks in eccentrically categorized folders known only to me.  So, as I find my own answers to porting my own code I’m going to post those answers here so I don’t have to try to remember later and maybe it’ll help someone else.

The first one is creating a grid.  I originally used this code from stackoverflow.  I used both the Matplotlib code and the final answer.  I prefer pure OpenCV answers to others, but the Matplotlib answer worked well.

I am reposting the OpenCV code Graham posited in case the original code is lost for whatever reason:

def draw_grid(img, line_color=(0, 255, 0), thickness=1, type_=_cv2.LINE_AA, pxstep=50):
    '''(ndarray, 3-tuple, int, int) -> void
    draw gridlines on img
    line_color:
        BGR representation of colour
    thickness:
        line thickness
    type:
        8, 4 or cv2.LINE_AA
    pxstep:
        grid line frequency in pixels
    '''
    x = pxstep
    y = pxstep
    while x < img.shape[1]:
        _cv2.line(img, (x, 0), (x, img.shape[0]), color=line_color, lineType=type_, thickness=thickness)
        x += pxstep

    while y < img.shape[0]:
        _cv2.line(img, (0, y), (img.shape[1], y), color=line_color, lineType=type_, thickness=thickness)
        y += pxstep

The function takes an image, line color, thickness, anti-aliased value (16 by the way), and 50 for the pixel steps.

The while loop is going to iterate over the x-axis and draw a line using a point to start to another point using the color we chose at the thickness we chose. Then again with the y-axis.

Translating this into opencv4nodejs isn’t that difficult.

The image object contains the /line/ function now it’s entitled /drawLine/ – the points are now Point objects instead of arrays of xy coordinates, and at the end there’s an object of named parameters.

Also, of note, the image object contains an array for the /sizes/ instead of a simple array value for the respective values.

We’ll pull that from opencv4nodejs like this:

const [imgHeight, imgWidth] = img.sizes;

In the Python example you’ll see img.shape[0] and img.shape[1] referring to the /y/ and /x/ values respectively.  Those are now imgHeight and imgWidth.

This line:

_cv2.line(img, (x, 0), (x, img.shape[0]), color=line_color, lineType=type_, thickness=thickness)

Becomes:

gridImg.drawLine(new cv.Point(x, 0), new cv.Point(x, imgHeight), { color: line_color, thickness: thickness });

The whole new code becomes:

const line_color = new cv.Vec(0, 255, 0);
const thickness = 1;
const pxstep = 50;
let x = pxstep;
let y = pxstep;

const [imgHeight, imgWidth] = img.sizes;

while (x < imgWidth) {
    gridImg.drawLine(new cv.Point(x, 0), new cv.Point(x, imgHeight), { color: line_color, thickness: thickness });
    x += pxstep;
}

while (y < imgHeight) {
    gridImg.drawLine(new cv.Point(0, y), new cv.Point(imgWidth, y), { color: line_color, thickness: thickness });
    y += pxstep
}

Which will display a green grid across an image like so:

Screen Shot 2019-02-08 at 13.51.06.png

You can massage the values to make the grid bigger or smaller as you want.  You will also notice it’s not symmetrical. it starts at 0,0 (upper left corner) and is 50px square. You could do some calculations to find out what a more even grid would look like instead of overlaying one section that’s smaller on the right and bottom.

Image credit:
I don’t know where I first found this image.  I’ve been using it for my OpenCV work for a while now.  There are copies out there here and here and after some digging, I found the answer I was looking for. The photo belongs to Markus J Grimm photography.  Give him a shout out – his work is superb and the other sites are just copies.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.