I'm not getting the Matrix output for Camera Caliberation. How can I get CamerMatrix, other results? - camera-calibration

!pip install numpy
!pip install matplotlib
!pip install opencv-python
import cv2
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from PIL import Image
import numpy as np
import glob
import os
import matplotlib.image as mpimg
import pickle
import_images
#images = # join all file .jpg in sample_chessboard dir to list
images = glob.glob('C:\Users\tamim\Downloads\Checkerboard8x11-20220609T003559Z-001\Checkerboard8x11/*.jpg')
# Define the chess board rows and columns
ChessboardSize = (11,8)
# Set the termination criteria for the corner sub-pixel algorithm
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 25, 0.001)
# Prepare the object points: (0,0,0), (1,0,0), (2,0,0), ..., (6,5,0). They are the same for all images
objectPoints = np.zeros((ChessboardSize[0] *ChessboardSize1 , 3), np.float32)
objectPoints[:, :2] = np.mgrid[0:ChessboardSize[0], 0:ChessboardSize1].T.reshape(-1, 2)
# Create the arrays to store the object points and the image points
objectPointsArray = []
imgPointsArray = []
for image in images:
print(image)
img = cv2.imread(image)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
**## Find the chaseboard corners**
ret, corners = cv2.findChessboardCorners(gray, ChessboardSize, None)
**## if found, add objectpoints, imagepoints (after refining them)**
if ret == true:
objectPointsArray.append(objectPoints)
corners2 = cv2.cornerSubPix(gray, corners, (11,11),(-1,-1), criteria)
imgPointsArray.append(corners)
image_with_corner = cv2.drawChessboardCorners(gray, ChessboardSize, corners2, ret)
**## Draw and display the corners**
img = cv2.drawChessboardCorners(img, ChessboardSize, coners2, ret)
cv2.imshow('image:',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# Calibrate a camera
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objectPointsArray, imgPointsArray, gray.shape[::-1],None,None)
enter image description here

Related

convert hued displot of X to plot of hue vs mode(X given hue)?

I have a Seaborn displot with a hued variable:
For each hued variable, I want to extract the mode of the density estimate and then plot each hue variable versus its mode, like so:
How do I do this?
You can use scipy.stats.gaussian_kde to create the density estimation function. And then call that function on an array of x-values to calculate its maximum.
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
df = pd.DataFrame({'x': np.random.normal(0.001, 1, 1300).cumsum() + 30,
'hue': np.repeat(np.arange(0.08, 0.20001, 0.01), 100).round(2)})
g = sns.displot(df, x='x', hue='hue', palette='turbo', kind='kde', fill=True, height=6, aspect=1.5)
plt.show()
from scipy.stats import gaussian_kde
from matplotlib.cm import ScalarMappable
fig, ax = plt.subplots(figsize=(10, 6))
hues = df['hue'].unique()
num_hues = len(hues)
colors = sns.color_palette('turbo', num_hues)
xmin, xmax = df['x'].min(), df['x'].max()
xs = np.linspace(xmin, xmax, 500)
for hue, color in zip(hues, colors):
data = df[df['hue'] == hue]['x'].values
kde = gaussian_kde(data)
mode_index = np.argmax(kde(xs))
mode_x = xs[mode_index]
sns.scatterplot(x=[hue], y=[mode_x], color=color, s=50, ax=ax)
cmap = sns.color_palette('turbo', as_cmap=True)
norm = plt.Normalize(hues.min(), hues.max())
plt.colorbar(ScalarMappable(cmap=cmap, norm=norm), ax=ax, ticks=hues)
plt.show()
Here is another approach, extracting the kde curves. It uses the legend of the kde plot to get the correspondence between the curves and the hue values. sns.kdeplot is the axes-level function used by sns.displot(kind='kde'). fill=False creates lines instead of filled polygons for the curves, for which the values are easier to extract. (ax1.fill_between can fill the curves during a second pass). The x and y axes of the second plot are switched to align the x-axes of both plots.
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
df = pd.DataFrame({'x': np.random.normal(0.007, 0.1, 1300).cumsum() + 30,
'hue': np.repeat(np.arange(0.08, 0.20001, 0.01), 100).round(2)})
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(12, 10), sharex=True)
sns.kdeplot(data=df, x='x', hue='hue', palette='turbo', fill=False, ax=ax1)
hues = [float(txt.get_text()) for txt in ax1.legend_.get_texts()]
ax2.set_yticks(hues)
ax2.set_ylabel('hue')
for hue, line in zip(hues, ax1.lines[::-1]):
color = line.get_color()
x = line.get_xdata()
y = line.get_ydata()
ax1.fill_between(x, y, color=color, alpha=0.3)
mode_ind = np.argmax(y)
mode_x = x[mode_ind]
sns.scatterplot(x=[mode_x], y=hue, color=color, s=50, ax=ax2)
sns.despine()
plt.tight_layout()
plt.show()

Animated Polar Plot

I am trying to make an animated plot of planetary motion using python. I can get the correct path to show up when not animated but once I try to animate it, it just shows up blank even though r and i are being output as the correct values when I try to print each value in the console.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
fig = plt.figure(figsize=(6,6))
ax = plt.subplot(111, polar=True)
ax.set_ylim(0,1)
line, = ax.plot([],[])
semi_major_axis = 1
eccentricity = 0.1
theta = np.linspace(0,2*np.pi, num = 50)
point, = ax.plot(0,1, marker="o")
def frame(i):
r=(semi_major_axis*(1-eccentricity**2)/(1-eccentricity*np.cos(i)))
line.set_xdata(i)
line.set_ydata(r)
return line,
ax.set_rmax(semi_major_axis+1)
ax.set_rticks(np.linspace(0,semi_major_axis+1, num = 5))
ax.set_rlabel_position(-22.5)
animation = FuncAnimation(fig, func=frame, frames=theta, interval=10)
plt.show()
I think the problem is you are plotting a point and not a line. The following code worked for me:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
fig = plt.figure(figsize=(6, 6))
ax = plt.subplot(111, polar=True)
ax.set_ylim(0, 1)
semi_major_axis = 1
eccentricity = 0.1
theta = np.linspace(0, 2 * np.pi, num=50)
def frame(i):
r = (semi_major_axis * (1 - eccentricity ** 2) / (1 - eccentricity * np.cos(i)))
ax.plot(i,r,'b', marker='o')
ax.set_rmax(semi_major_axis + 1)
ax.set_rticks(np.linspace(0, semi_major_axis + 1, num=5))
ax.set_rlabel_position(-22.5)
animation = FuncAnimation(fig, func=frame, frames=theta, interval=10)
plt.show()

Image segmentation based on mouse click

Using python framework we are able to create image segments as shown in attachment. Now, based on the mouse click in the image segment we need to highlight the segment with specific color.
Based on the mouse click I am able to get x/y coordinates of the specific location. Please suggest me how can I check on which image segment the coordinates belongs to?
The following is the code snippet:
from skimage.segmentation import felzenszwalb, slic,quickshift
from skimage.segmentation import mark_boundaries
from skimage.segmentation import find_boundaries
from skimage.util import img_as_float
from skimage import io
import matplotlib.pyplot as plt
from skimage import measure
from skimage import restoration
from skimage import img_as_float
import numpy as np
coords = []
def find_nearest(array,value):
idx = (np.abs(array-value)).argmin()
return array[idx]
def onclick(event):
global ix, iy
ix, iy = event.xdata, event.ydata
print ('ix ',ix)
print ("iy ",iy)
color = np.float64([1,0,1]) # red color
image[segments == 14] = color
mark_boundaries(image, segments)
ax.imshow(mark_boundaries(image, segments))
coords.append((ix, iy))
return
image=img_as_float(io.imread("amazon.jpg"))
segments = quickshift(image, ratio=1.0, kernel_size=20, max_dist=10,
return_tree=False, sigma=0, convert2lab=True, random_seed=42)
fig = plt.figure("Superpixels -- %d segments" % (500))
ax = fig.add_subplot(1, 1, 1)
fig,ax = plt.subplots()
color = np.float64([1,0,0])
image[segments == 14] = color # desired segment to be colored
fig.canvas.mpl_connect('button_press_event', onclick)
ax.imshow(mark_boundaries(image, segments))
plt.axis("off")
plt.show()
According to the documentation, quickshift returns an integer mask indicating segment labels. If you know what pixel the user clicked on, you can check the value of that pixel in your variable segments to get the segment number.
In you click handler, you can use
clicked_segment = segments[event.xdata, event.ydata]

Dynamic plot in python

I'm trying to create a plot in Python where the data that is being plotted gets updated as my simulation progresses. In MATLAB, I could do this with the following code:
t = linspace(0, 1, 100);
figure
for i = 1:100
x = cos(2*pi*i*t);
plot(x)
drawnow
end
I'm trying to use matplotlib's FuncAnimation function in the animation module to do this inside a class. It calls a function plot_voltage which recalculates voltage after each timestep in my simulation. I have it set up as follows:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
def __init__(self):
ani = animation.FuncAnimation(plt.figure(2), self.plot_voltage)
plt.draw()
def plot_voltage(self, *args):
voltages = np.zeros(100)
voltages[:] = np.nan
# some code to calculate voltage
ax1 = plt.figure(2).gca()
ax1.clear()
ax1.plot(np.arange(0, len(voltages), 1), voltages, 'ko-')`
When my simulation runs, the figures show up but just freeze. The code runs without error, however. Could someone please let me know what I am missing?
Here is a translation of the matlab code into matplotlib using FuncAnimation:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
t = np.linspace(0, 1, 100)
fig = plt.figure()
line, = plt.plot([],[])
def update(i):
x = np.cos(2*np.pi*i*t)
line.set_data(t,x)
ani = animation.FuncAnimation(fig, update,
frames=np.linspace(1,100,100), interval=100)
plt.xlim(0,1)
plt.ylim(-1,1)
plt.show()

matplotlib: jpg image special effect/transformation as if its on a page of an open book

I wish to appear a figure (and certain text) as if they are printed on a page of an open book. Is it possible to transform an jpg image programmatically or in matplotlib to have such an effect?
You can use a background axis along with an open source book image to do something like this,
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_axes([0.1, 0.1, 0.8, 0.8])
ax2 = fig.add_axes([0.2, 0.3, 0.25, 0.3])
#Plot page from a book
im = plt.imread("./book_page.jpg")
implot = ax1.imshow(im, origin='lower')
# Plot a graph and set background to transparent
x = np.linspace(0,4.*np.pi,40)
y = np.sin(x)
ax2.plot(x,y,'-ro',alpha=0.5)
ax2.set_ylim([-1.1,1.1])
ax2.patch.set_alpha(0.0)
from matplotlib import rc
rc('text', usetex=True)
margin = im.shape[0]*0.075
ytext = im.shape[1]/2.+10
ax1.text(margin, ytext, "The following text is an example")
ax1.text(margin, 90, "Figure 1. Showing a sine function")
plt.show()
Which looks like this,
where I used the following book image.
UPDATE: Added non-affine transformation based on scikit-image warp example, but with Maxwell distribution. The solution saves the matplotlib line as an image in order to apply a pointwise transform. Mapping for vector graphics may be possible but I think this will be more complicated...
import numpy as np
import matplotlib.pyplot as plt
def maxwellian_transform_image(image):
from skimage.transform import PiecewiseAffineTransform, warp
rows, cols = image.shape[0], image.shape[1]
src_cols = np.linspace(0, cols, 20)
src_rows = np.linspace(0, rows, 10)
src_rows, src_cols = np.meshgrid(src_rows, src_cols)
src = np.dstack([src_cols.flat, src_rows.flat])[0]
# add maxwellian to row coordinates
x = np.linspace(0, 3., src.shape[0])
dst_rows = src[:, 1] + (np.sqrt(2/np.pi)*x**2 * np.exp(-x**2/2)) * 50
dst_cols = src[:, 0]
dst_rows *= 1.5
dst_rows -= 1.0 * 50
dst = np.vstack([dst_cols, dst_rows]).T
tform = PiecewiseAffineTransform()
tform.estimate(src, dst)
out_rows = image.shape[0] - 1.5 * 50
out_cols = cols
out = warp(image, tform, output_shape=(out_rows, out_cols))
return out
#Create the new figure
fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
#Plot page from a book
im = plt.imread("./book_page.jpg")
implot = ax.imshow(im, origin='lower')
# Plot and save graph as image, will need some manipulation of location
temp, at = plt.subplots()
margin = im.shape[0]*0.1
x = np.linspace(margin,im.shape[0]/2.,40)
y = im.shape[1]/3. + 0.1*im.shape[1]*np.sin(12.*np.pi*x/im.shape[0])
at.plot(x,y,'-ro',alpha=0.5)
temp.savefig("lineplot.png",transparent=True)
#Read in plot as an image and apply transform
plot = plt.imread("./lineplot.png")
out = maxwellian_transform_image(plot)
ax.imshow(out, extent=[0,im.shape[1],0,im.shape[0]])
plt.show()
The figure now looks like,

Resources