[PYTHON] Make a chessboard pattern for camera calibration

Postscript

I deployed the following logic in a web app. Please use it if you like. https://checkerboardwebapp.herokuapp.com/

Heroku's free tier is 600 hours, so you may not be able to use it in some cases. Well it will be okay. I don't think anyone will use it. I made it almost for myself, so it's pretty rough. It's not so good, so it's better to use the official OpenCV here.

Introduction

Good evening I usually make black and white tiles (chess board pattern) for calibration using software called ARCAD. It is troublesome to remake it every time the tile size changes, so I tried to find out if it could be made easily. When I looked it up, there was a library that could easily draw figures in PDF, so I implemented it. It is unknown how far it can be used because it was not actually printed and verified. I'm likely to have a chance to use it often in the future I wondered if I could use it anywhere if I published it as a WEB application.

Thing you want to do

I want to make something like ↓ by specifying the actual size (mm) image.png

environment

python:3.8 Library used: reportlab

Make black and white tiles for calibration

I implemented the code of ↓

box_grid.py


#! /usr/bin/python
# -*- coding: utf-8 -*-
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A1, A2, A3, A4,landscape, portrait
from reportlab.lib.units import cm, mm

FILE_NAME = './box_grid_calibration.pdf'
#Vertical
VERTICAL_SIZE = 28
#side
HORIZONTAL_SIZE = 19
#Starting position
START_X = 10.0*mm
START_Y = 10.0*mm
#Square size
RECT_SIZE = 10.0*mm

if __name__ == '__main__':
    #A4 portrait
    pdf_canvas = canvas.Canvas(FILE_NAME, pagesize=portrait(A4))
    #A4 sideways
    # pdf_canvas = canvas.Canvas(FILE_NAME, pagesize=landscape(A4))
    pdf_canvas.saveState()

    cnt_flag = True

    X, Y = START_X, START_Y
    #Vertical drawing
    for i in range(VERTICAL_SIZE):
        #Horizontal drawing
        for j in range(HORIZONTAL_SIZE):
            #Draw white and black alternately
            pdf_canvas.setFillColorRGB(255, 255, 255) if cnt_flag else pdf_canvas.setFillColorRGB(0, 0, 0)
            pdf_canvas.rect(X, Y, RECT_SIZE, RECT_SIZE, stroke=0, fill=1)
            #Shift the X position
            X += RECT_SIZE
            #Flag reversal
            cnt_flag = not cnt_flag

        #If it is an even number, black and white do not alternate, so the flag is inverted once.
        if HORIZONTAL_SIZE % 2 == 0:
            cnt_flag = not cnt_flag

        #Return to the X coordinate start point
        X = START_X
        #Shift Y position
        Y += RECT_SIZE

    pdf_canvas.restoreState()
    pdf_canvas.save()

When executed, here will be created.

FILE_NAME = './box_grid_calibration.pdf'
#Vertical
VERTICAL_SIZE = 28
#side
HORIZONTAL_SIZE = 19
#Starting position
START_X = 10.0*mm
START_Y = 10.0*mm
#Square size
RECT_SIZE = 10.0*mm

I don't think it needs explanation, but the above items determine the number of rows, the number of columns, the drawing start position, and the tile size. As a caveat, reportlab seems to have different origin coordinates from normal images, It seems that the Y-axis becomes positive toward the top of the lower left origin. The X axis is the same. The image is below. Y axis ↑ | | ● --- → X-axis

I also made an alternate and aligned version of the disk.

Alternating pattern

circle_grid.py


#! /usr/bin/python
# -*- coding: utf-8 -*-
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A1, A2, A3, A4,landscape, portrait
from reportlab.lib.units import cm, mm

FILE_NAME = './circle_grid_calibration.pdf'
#Vertical
VERTICAL_SIZE = 28
#side
HORIZONTAL_SIZE = 19
#Starting position
START_X = 10.0*mm
START_Y = 10.0*mm
#Circular radius size
RADIUS = 5.0*mm

if __name__ == '__main__':
    #A4 portrait
    pdf_canvas = canvas.Canvas(FILE_NAME, pagesize=portrait(A4))
    #A4 sideways
    # pdf_canvas = canvas.Canvas(FILE_NAME, pagesize=landscape(A4))
    pdf_canvas.saveState()

    cnt_flag = True

    X, Y = START_X, START_Y
    #Vertical drawing
    for i in range(VERTICAL_SIZE):
        #Horizontal drawing
        for j in range(HORIZONTAL_SIZE):
            #Draw white and black alternately
            pdf_canvas.setFillColorRGB(255, 255, 255) if cnt_flag else pdf_canvas.setFillColorRGB(0, 0, 0)
            pdf_canvas.circle(X, Y, RADIUS, stroke=0, fill=1)
            #Shift the X position
            X += RADIUS * 2
            #Flag reversal
            cnt_flag = not cnt_flag

        #If it is an even number, black and white do not alternate, so the flag is inverted once.
        if HORIZONTAL_SIZE % 2 == 0:
            cnt_flag = not cnt_flag

        #Return to the X coordinate start point
        X = START_X
        #Shift Y position
        Y += RADIUS * 2

    pdf_canvas.restoreState()
    pdf_canvas.save()

I ran here

Alignment pattern

circle_grid2.py


#! /usr/bin/python
# -*- coding: utf-8 -*-
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A1, A2, A3, A4,landscape, portrait
from reportlab.lib.units import cm, mm

FILE_NAME = './circle_grid2_calibration.pdf'
#Vertical
VERTICAL_SIZE = 19
#side
HORIZONTAL_SIZE = 13
#Starting position
START_X = 10.0*mm
START_Y = 10.0*mm
#Circular radius size
RADIUS = 5.0*mm

if __name__ == '__main__':
    #A4 portrait
    pdf_canvas = canvas.Canvas(FILE_NAME, pagesize=portrait(A4))
    #A4 sideways
    # pdf_canvas = canvas.Canvas(FILE_NAME, pagesize=landscape(A4))
    pdf_canvas.saveState()

    cnt_flag = True

    X, Y = START_X, START_Y
    #Vertical drawing
    for i in range(VERTICAL_SIZE):
        #Horizontal drawing
        for j in range(HORIZONTAL_SIZE):
            #Do nothing if even times
            if not cnt_flag:
                #Flag reversal
                cnt_flag = not cnt_flag
                continue
            #Set black
            pdf_canvas.setFillColorRGB(0, 0, 0)
            pdf_canvas.circle(X, Y, RADIUS, stroke=0, fill=1)
            #Shift the X position
            X += RADIUS * 3

        #Return to the X coordinate start point
        X = START_X
        #Shift Y position
        Y += RADIUS * 3

    pdf_canvas.restoreState()
    pdf_canvas.save()

I ran here

Reference URL / Source

https://kuratsuki.net/2018/06/python-3-%E3%81%AE-reportlab-%E3%81%A7-pdf-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E7%94%9F%E6%88%90%E3%81%99%E3%82%8B/ https://symfoware.blog.fc2.com/blog-entry-769.html Thanks for the URL above.

Recommended Posts

Make a chessboard pattern for camera calibration
Make a Tweet box for Pepper
Camera calibration
How to make a unit test Part.1 Design pattern for introduction
Make Qt for Python app a desktop app
ROS course 107 Make a client for rosblidge
Let's make a Backend plugin for Errbot
Make a bot for Skype on EC2 (CentOS)
Make a histogram for the time being (matplotlib)
Make for VB6.
Let's make a module for Python using SWIG
A supplement to "Camera Calibration" in OpenCV-Python Tutorials
[For play] Let's make Yubaba a LINE Bot (Python)
Make a squash game
Make a distance matrix
I'll make a password!
Visually understand camera calibration
Make a Nyan button
Make a Tetris-style game!
Make a Base64 decoder
Experiment to make a self-catering PDF for Kindle with Python
How to make a Python package (written for an intern)