9/14/2023

convert you opencv camera calibration yaml file to openSFM camera.json file

 refer to code:


.

from PIL import Image
import json
import yaml
import os
import argparse

def get_image_dimensions(image_path):
with Image.open(image_path) as img:
return img.size

def convert_yaml_to_opensfm_json(yaml_file, json_file, image_path):
image_width, image_height = get_image_dimensions(image_path)

with open(yaml_file, 'r') as f:
calibration_data = yaml.safe_load(f)

# Extract the camera matrix and distortion coefficients
camera_matrix = calibration_data['camera_matrix']
dist_coeff = calibration_data['dist_coeff']

# Compute the normalized focal length
focal_normalized = camera_matrix[0][0] / image_width

# Prepare the JSON data
json_data = {
f"custom_camera {image_width} {image_height} perspective 0.0": {
"projection_type": "perspective",
"width": image_width,
"height": image_height,
"focal": focal_normalized,
"k1": dist_coeff[0][0],
"k2": dist_coeff[0][1]
}
}

# Write the JSON data to file
with open(json_file, 'w') as f:
json.dump(json_data, f, indent=4)

def main():
yaml_file="calibration.yaml"
json_file="./camera_models.json"
image_path="IMG_5306.JPG"
convert_yaml_to_opensfm_json(yaml_file, json_file, image_path)

if __name__ == '__main__':
main()

..


reference :

https://github.com/mapillary/OpenSfM/issues/95

https://opensfm.org/docs/geometry.html#camera-models


Thank you.

www.marearts.com

🙇🏻‍♂️


python print exponential notation

 refer to code:


-

x = 0.003
formatted_x = "{:.1e}".format(x)
print(formatted_x) # Output will be "3.0e-03"

--




9/13/2023

print docker memory usage size and image size on command line

Print docker container men usage 

.

docker stats --no-stream --format "table {{.Container}}\t{{.MemUsage}}"
CONTAINER MEM USAGE / LIMIT
df1db3352f5c 62.85MiB / 7.581GiB
e225c0866cef 778.8MiB / 7.581GiB
8e40a961b59d 1.121GiB / 7.581GiB
f66e33681593 173MiB / 7.581GiB

..

Print image size

.

docker ps --format '{{.Image}}' | uniq | xargs -I {} docker image ls --format "table {{.Repository}}\t{{.Size}}" {}
REPOSITORY SIZE
5978.com/fast-api 643MB
REPOSITORY SIZE
5978.com/recognition 2.52GB
REPOSITORY SIZE
5978.com/detector 746MB

..


.

All together 

#!/bin/bash
echo "Memory Usage of Running Containers:"
docker stats --no-stream --format "table {{.Container}}\t{{.MemUsage}}"
echo ""

echo "Image Size of Running Containers:"
docker ps --format '{{.Image}}' | uniq | xargs -I {} docker image ls --format "table {{.Repository}}\t{{.Size}}" {}

..


Thank you.

www.marearts.com

🙇🏻‍♂️

OpenCV Camera Calibration source code

refer to code:

.

import numpy as np
import cv2
import glob
import yaml
from icecream import ic
import os

def calibrate_camera(images, chess_box_scale_mm):
# Termination criteria for refining the detected corners
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

# Prepare object points: (0,0,0), (1,0,0), (2,0,0), ..., (9,6,0)
objp = np.zeros((9*6,3), np.float32)
objp[:,:2] = np.mgrid[0:6, 0:9].T.reshape(-1,2) * chess_box_scale_mm# Scale by 7.5mm or 17.5mm or 25mm

# Arrays to store object and image points from all the images
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane

if not images:
raise Exception("No images found in the calibration directory.")

for fname in images:
ic(fname)
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Find the chessboard corners
ret, corners = cv2.findChessboardCorners(gray, (6,9), None)
ic(ret)

# If found, add object points and image points
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, (6,9), corners2, ret)
# Save the image with corners in the same directory but with a .png extension
base_name = os.path.basename(fname)
file_root, file_ext = os.path.splitext(base_name)
save_path = os.path.join(os.path.dirname(fname), f"{file_root}.png")
cv2.imwrite(save_path, img)
cv2.imshow('img', img)
cv2.waitKey(500)


cv2.destroyAllWindows()

if not objpoints or not imgpoints:
raise Exception("Chessboard corners not found in any images.")

# Calibrate the camera using the last value of gray from the loop
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
return ret, mtx, dist, rvecs, tvecs

def main():
path = "./path/to/images/"
images = glob.glob(f'{path}/*.JPG')

ret, mtx, dist, rvecs, tvecs = calibrate_camera(images, 7.5) #chess_box_scale_mm is 7.5 mm

print("Camera matrix: \n", mtx)
print("Distortion coefficients: \n", dist)

# Save to YAML file
data = {'camera_matrix': np.asarray(mtx).tolist(), 'dist_coeff': np.asarray(dist).tolist()}
with open(f"{path}/calibration.yaml", "w") as f:
yaml.dump(data, f)

# Display one of the images after undistortion
img = cv2.imread(images[0]) # Replace with an image from your calibration set
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.imshow('origin Image', img)
cv2.imshow('Undistorted Image', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

if __name__ == "__main__":
main()

.. 


Here is chess board which has 10x7.


png files in same folder are that images succeed for finding pattern.

yaml file will be generated in image folder for camera intrinsic params.


Thank you.

www.marearts.com

🙇🏻‍♂️


9/11/2023

docker Multi-Architecture Builds



Multi-Architecture Builds

Docker's Buildx extension allows you to build multi-architecture images. You can specify multiple target architectures and create a single image that works on both. Here's a simplified example:

This will create an image that can run on both Intel (amd64) and ARM (arm64) based systems.


# Initialize Buildx (one-time operation)
docker buildx create --use

# Build multi-architecture image
docker buildx build --platform linux/amd64,linux/arm64 -t your-image-name:tag .

comparing t4g.medium, t3a.medium, and t3.medium

 



the t4g.medium, t3a.medium, and t3.medium are all part of Amazon's EC2 T-series instances, which are designed to provide a baseline level of CPU performance with the ability to burst above the baseline when needed. However, they differ in the underlying processor architecture and some other characteristics. Below is a comparative table:

Instance TypeCPU TypevCPUsMemory (GiB)ProcessorNetwork BandwidthEBS Bandwidth
t4g.mediumARM-based24Graviton2Up to 5 GbpsUp to 3.5 Gbps
t3a.mediumAMD-based24AMD EPYC 7000 seriesUp to 5 GbpsUp to 3.5 Gbps
t3.mediumIntel-based24Intel Xeon Scalable (Skylake and Broadwell options)Up to 5 GbpsUp to 3.5 Gbps

Key Differences:

  1. Processor Architecture:

    • t4g.medium uses ARM-based Graviton2 processors.
    • t3a.medium uses AMD EPYC 7000 series processors.
    • t3.medium uses Intel Xeon Scalable processors.
  2. Price:

    • t3a.medium instances are generally cheaper than t3.medium instances but offer similar performance characteristics.
    • t4g.medium instances are also generally cost-effective due to the efficiency of the Graviton2 processor.
  3. Performance:

    • The ARM-based Graviton2 processors in t4g.medium instances are designed for better power efficiency.
    • Both AMD and Intel options in t3a and t3 are more traditional and have been in use for longer periods, and their performance characteristics are well understood.
  4. Compatibility:

    • Software that is dependent on specific instruction sets might not be compatible with ARM-based processors, so t3 and t3a could be a safer bet for those applications.

For the most current and accurate information, it's always best to consult the official AWS EC2 documentation or pricing pages.

9/05/2023

Saving additional file while pytorch lightning training.

 if you want to save some additional file in checkpoints where PyTorch lightning save latest or best model in certain folder automatically, add this function in 

.

#training class using pl
class my_trainer(pl.LightningModule):
def __init__(self, cfg):
super().__init__()

..

add this model to save additional file

.

def on_save_checkpoint(self, checkpoint):
# Call the parent method first (optional)
super().on_save_checkpoint(checkpoint)
# Your custom code to save additional files
dirpath = None
for callback in self.trainer.callbacks:
if isinstance(callback, ModelCheckpoint):
dirpath = callback.dirpath
break

if dirpath is not None:
additional_filepath = os.path.join(dirpath, "my_additional_file.txt")
with open(additional_filepath, "w") as f:
f.write("Some additional data")
print(f"Saved additional file to {additional_filepath}")
else:
print("Could not find ModelCheckpoint dirpath to save additional file.")

..

ok, now try it!

Good luck!


www.marearts.com