Module ReMake.Raspberry_Pi.calibration
Expand source code
from os.path import exists
import numpy as np
import cv2
import glob
import yaml
from PIL import Image
#import picamera
import time
class calibration:
"""This class implements the calibration algorithm for the Raspberry Pi Camera and can be used to generate the distortion coefficients matrix for a specific resolution.
"""
def __init__(self, r=0) -> None:
"""The calibartion object used to generate the distortion matrix.
Args:
r (int, optional): resolution used to compute the matrix. Defaults to 0.
"""
self.res = [(1280, 720), (4056, 3040)]
self.r=r
def setRes(self, i):
"""Set the resolution of the scan.
Args:
i (int): the resolution of the scan
"""
self.r = i
def setResxy(self, x, y):
"""Set the resolution of the scan by vertical and horizontal components but only if it is supported.
Args:
x (int): horizontal resolution
y (int): vertical resolution
"""
try:
index = self.res.index((x,y))
self.r = index
except:
print("THE RESOLUTION ISN'T SUPPORTED")
def save_coefficients(self, mtx, dist, path):
"""Save the camera matrix and the distortion coefficients to given path/file.
Args:
mtx (nparray): distortion matrix coefficients K
dist (nparray): distortion matrix coefficients D
path (str): location where the matrix should be saved
"""
cv_file = cv2.FileStorage(path, cv2.FILE_STORAGE_WRITE)
cv_file.write("K", mtx)
cv_file.write("D", dist)
# note you *release* you don't close() a FileStorage object
cv_file.release()
def getRes(self):
"""Get the resolution of the scan.
Returns:
list: resolution of the scan
"""
return self.res[self.r]
def getimg(self, n):
"""Take a series of picture using the Raspberry Pi Camera and save them locally.
Args:
n (int): number of picture to take
"""
with picamera.PiCamera() as camera:
camera.resolution = self.getRes()
camera.framerate = 1
# Wait for the automatic gain control to settle
time.sleep(2)
# Now fix the values
#camera.shutter_speed = camera.exposure_speed
#camera.exposure_mode = 'off'
#g = camera.awb_gains
#camera.awb_mode = 'off'
#camera.awb_gains = g
# Finally, take several photos with the fixed settings
camera.capture_sequence(['cal/img%02d.jpg' % i for i in range(n)])
def genMatrix(self):
"""Generate the distortion matrix.
"""
self.getimg(10)
# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((9*6,3), np.float32)
objp[:,:2] = np.mgrid[0:9,0:6].T.reshape(-1,2)
# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.
images = glob.glob('cal/*.jpg')
print(len(images))
for fname in images:
img = cv2.imread(fname)
if not (img is None):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#cv2.imshow('img',gray)
#cv2.waitKey(500)
# Find the chess board corners
ret, corners = cv2.findChessboardCorners(gray, (9,6),None)
# If found, add object points, image points (after refining them)
if ret == True:
objpoints.append(objp)
corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
imgpoints.append(corners2)
# Draw and display the corners
#cv2.drawChessboardCorners(img, (9,6), corners2,ret)
#cv2.imshow('img',img)
#cv2.imwrite('test.jpg',img)
#cv2.waitKey(500)
#print(objpoints)
#print('--------------------')
#print(imgpoints)
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
#print('ret={}, mtx={}, dist={}, rvecs={}, tvecs={}'.format(ret, mtx, dist, rvecs, tvecs))
#img = cv2.imread('im0.jpg')
#h, w = img.shape[:2]
#newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))
# undistort
#dst = cv2.undistort(img, mtx, dist, None, newcameramtx)
# crop the image
#x,y,w,h = roi
#dst = dst[y:y+h, x:x+w]
#cv2.imwrite('calibresult.png',dst)
self.save_coefficients(mtx, dist, '/home/pi/TestCamera/coef{}.yml'.format(self.r))
def getMatrix(self):
"""Get the name of the file containing the distortion matrix.
Returns:
str: name of the distortion matrix or -1 if it doesn't exists.
"""
matrix = 'coef{}.yml'.format(self.r)
if exists(matrix):
return matrix
return -1
Classes
class calibration (r=0)
-
This class implements the calibration algorithm for the Raspberry Pi Camera and can be used to generate the distortion coefficients matrix for a specific resolution.
The calibartion object used to generate the distortion matrix.
Args
r
:int
, optional- resolution used to compute the matrix. Defaults to 0.
Expand source code
class calibration: """This class implements the calibration algorithm for the Raspberry Pi Camera and can be used to generate the distortion coefficients matrix for a specific resolution. """ def __init__(self, r=0) -> None: """The calibartion object used to generate the distortion matrix. Args: r (int, optional): resolution used to compute the matrix. Defaults to 0. """ self.res = [(1280, 720), (4056, 3040)] self.r=r def setRes(self, i): """Set the resolution of the scan. Args: i (int): the resolution of the scan """ self.r = i def setResxy(self, x, y): """Set the resolution of the scan by vertical and horizontal components but only if it is supported. Args: x (int): horizontal resolution y (int): vertical resolution """ try: index = self.res.index((x,y)) self.r = index except: print("THE RESOLUTION ISN'T SUPPORTED") def save_coefficients(self, mtx, dist, path): """Save the camera matrix and the distortion coefficients to given path/file. Args: mtx (nparray): distortion matrix coefficients K dist (nparray): distortion matrix coefficients D path (str): location where the matrix should be saved """ cv_file = cv2.FileStorage(path, cv2.FILE_STORAGE_WRITE) cv_file.write("K", mtx) cv_file.write("D", dist) # note you *release* you don't close() a FileStorage object cv_file.release() def getRes(self): """Get the resolution of the scan. Returns: list: resolution of the scan """ return self.res[self.r] def getimg(self, n): """Take a series of picture using the Raspberry Pi Camera and save them locally. Args: n (int): number of picture to take """ with picamera.PiCamera() as camera: camera.resolution = self.getRes() camera.framerate = 1 # Wait for the automatic gain control to settle time.sleep(2) # Now fix the values #camera.shutter_speed = camera.exposure_speed #camera.exposure_mode = 'off' #g = camera.awb_gains #camera.awb_mode = 'off' #camera.awb_gains = g # Finally, take several photos with the fixed settings camera.capture_sequence(['cal/img%02d.jpg' % i for i in range(n)]) def genMatrix(self): """Generate the distortion matrix. """ self.getimg(10) # termination criteria criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) # prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0) objp = np.zeros((9*6,3), np.float32) objp[:,:2] = np.mgrid[0:9,0:6].T.reshape(-1,2) # Arrays to store object points and image points from all the images. objpoints = [] # 3d point in real world space imgpoints = [] # 2d points in image plane. images = glob.glob('cal/*.jpg') print(len(images)) for fname in images: img = cv2.imread(fname) if not (img is None): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #cv2.imshow('img',gray) #cv2.waitKey(500) # Find the chess board corners ret, corners = cv2.findChessboardCorners(gray, (9,6),None) # If found, add object points, image points (after refining them) if ret == True: objpoints.append(objp) corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria) imgpoints.append(corners2) # Draw and display the corners #cv2.drawChessboardCorners(img, (9,6), corners2,ret) #cv2.imshow('img',img) #cv2.imwrite('test.jpg',img) #cv2.waitKey(500) #print(objpoints) #print('--------------------') #print(imgpoints) ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None) #print('ret={}, mtx={}, dist={}, rvecs={}, tvecs={}'.format(ret, mtx, dist, rvecs, tvecs)) #img = cv2.imread('im0.jpg') #h, w = img.shape[:2] #newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h)) # undistort #dst = cv2.undistort(img, mtx, dist, None, newcameramtx) # crop the image #x,y,w,h = roi #dst = dst[y:y+h, x:x+w] #cv2.imwrite('calibresult.png',dst) self.save_coefficients(mtx, dist, '/home/pi/TestCamera/coef{}.yml'.format(self.r)) def getMatrix(self): """Get the name of the file containing the distortion matrix. Returns: str: name of the distortion matrix or -1 if it doesn't exists. """ matrix = 'coef{}.yml'.format(self.r) if exists(matrix): return matrix return -1
Methods
def genMatrix(self)
-
Generate the distortion matrix.
Expand source code
def genMatrix(self): """Generate the distortion matrix. """ self.getimg(10) # termination criteria criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) # prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0) objp = np.zeros((9*6,3), np.float32) objp[:,:2] = np.mgrid[0:9,0:6].T.reshape(-1,2) # Arrays to store object points and image points from all the images. objpoints = [] # 3d point in real world space imgpoints = [] # 2d points in image plane. images = glob.glob('cal/*.jpg') print(len(images)) for fname in images: img = cv2.imread(fname) if not (img is None): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #cv2.imshow('img',gray) #cv2.waitKey(500) # Find the chess board corners ret, corners = cv2.findChessboardCorners(gray, (9,6),None) # If found, add object points, image points (after refining them) if ret == True: objpoints.append(objp) corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria) imgpoints.append(corners2) # Draw and display the corners #cv2.drawChessboardCorners(img, (9,6), corners2,ret) #cv2.imshow('img',img) #cv2.imwrite('test.jpg',img) #cv2.waitKey(500) #print(objpoints) #print('--------------------') #print(imgpoints) ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None) #print('ret={}, mtx={}, dist={}, rvecs={}, tvecs={}'.format(ret, mtx, dist, rvecs, tvecs)) #img = cv2.imread('im0.jpg') #h, w = img.shape[:2] #newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h)) # undistort #dst = cv2.undistort(img, mtx, dist, None, newcameramtx) # crop the image #x,y,w,h = roi #dst = dst[y:y+h, x:x+w] #cv2.imwrite('calibresult.png',dst) self.save_coefficients(mtx, dist, '/home/pi/TestCamera/coef{}.yml'.format(self.r))
def getMatrix(self)
-
Get the name of the file containing the distortion matrix.
Returns
str
- name of the distortion matrix or -1 if it doesn't exists.
Expand source code
def getMatrix(self): """Get the name of the file containing the distortion matrix. Returns: str: name of the distortion matrix or -1 if it doesn't exists. """ matrix = 'coef{}.yml'.format(self.r) if exists(matrix): return matrix return -1
def getRes(self)
-
Get the resolution of the scan.
Returns
list
- resolution of the scan
Expand source code
def getRes(self): """Get the resolution of the scan. Returns: list: resolution of the scan """ return self.res[self.r]
def getimg(self, n)
-
Take a series of picture using the Raspberry Pi Camera and save them locally.
Args
n
:int
- number of picture to take
Expand source code
def getimg(self, n): """Take a series of picture using the Raspberry Pi Camera and save them locally. Args: n (int): number of picture to take """ with picamera.PiCamera() as camera: camera.resolution = self.getRes() camera.framerate = 1 # Wait for the automatic gain control to settle time.sleep(2) # Now fix the values #camera.shutter_speed = camera.exposure_speed #camera.exposure_mode = 'off' #g = camera.awb_gains #camera.awb_mode = 'off' #camera.awb_gains = g # Finally, take several photos with the fixed settings camera.capture_sequence(['cal/img%02d.jpg' % i for i in range(n)])
def save_coefficients(self, mtx, dist, path)
-
Save the camera matrix and the distortion coefficients to given path/file.
Args
mtx
:nparray
- distortion matrix coefficients K
dist
:nparray
- distortion matrix coefficients D
path
:str
- location where the matrix should be saved
Expand source code
def save_coefficients(self, mtx, dist, path): """Save the camera matrix and the distortion coefficients to given path/file. Args: mtx (nparray): distortion matrix coefficients K dist (nparray): distortion matrix coefficients D path (str): location where the matrix should be saved """ cv_file = cv2.FileStorage(path, cv2.FILE_STORAGE_WRITE) cv_file.write("K", mtx) cv_file.write("D", dist) # note you *release* you don't close() a FileStorage object cv_file.release()
def setRes(self, i)
-
Set the resolution of the scan.
Args
i
:int
- the resolution of the scan
Expand source code
def setRes(self, i): """Set the resolution of the scan. Args: i (int): the resolution of the scan """ self.r = i
def setResxy(self, x, y)
-
Set the resolution of the scan by vertical and horizontal components but only if it is supported.
Args
x
:int
- horizontal resolution
y
:int
- vertical resolution
Expand source code
def setResxy(self, x, y): """Set the resolution of the scan by vertical and horizontal components but only if it is supported. Args: x (int): horizontal resolution y (int): vertical resolution """ try: index = self.res.index((x,y)) self.r = index except: print("THE RESOLUTION ISN'T SUPPORTED")