I am using open3d to render a 3D head together with a hairstyle (see code below). I am now looking for a way to take a screenshot of the rendered objects. How do you suggest proceeding? I need to consider a few hundred hairstyles, so I would prefer to avoid using mouse or keyboard control.
All 3D objects (head and hairstyle) are from this dataset.
This is the script I'm using to visualize the 3D head model and the hairstyle:
import open3d as o3d
import math
from mathutils import Vector
import struct
import array
import numpy as np
# Load the head model
mesh = o3d.io.read_triangle_mesh("../head_model.obj")
# Load a 3D hairstyle
fin = open("../strands00144.data", "rb")
num_of_strands = struct.unpack('i', fin.read(4))[0]
hair = []
num_strand = 0
#print("num_of_strands: ", num_of_strands)
for i in range(num_of_strands):
num_of_vertices = struct.unpack('i', fin.read(4))[0]
if num_of_vertices == 100:
num_strand += 1
#print("num_of_vertices: ", num_of_vertices)
strand = []
for j in range(num_of_vertices):
vertex_x = struct.unpack('f', fin.read(4))[0]
vertex_y = struct.unpack('f', fin.read(4))[0]
vertex_z = struct.unpack('f', fin.read(4))[0]
vertex = [vertex_x, vertex_y, vertex_z]
#print("vertex: ", vertex)
strand.append(vertex)
hair.append(strand)
randomPoints = np.zeros([100*num_strand, 3])
for ii in range(num_strand):
randomPoints[0 + 100 * ii: 100 + 100 * ii][:] = hair[ii][:][:]
o3d.visualization.Visualizer()
pointSet = o3d.geometry.PointCloud()
pointSet.points = o3d.utility.Vector3dVector(randomPoints)
pointSet.paint_uniform_color([0, 0, 0])
mesh.compute_vertex_normals()
o3d.visualization.draw_geometries([pointSet, mesh])
Related
I'm trying to use the OpenCV Python wrapper to calculate the Discrete wavelet Haar transform for an image. Supposedly, images == numpy arrays == CV matrices, so I thought this should work:
import cv2
import numpy as np
import pywt
from pywt import wavedec
import csv
imgcv1 = cv2.split(resize)[0]
cv2.boxFilter(imgcv1, 0, (7,7), imgcv1, (-1,-1), False, cv2.BORDER_DEFAULT)
cv2.resize( imgcv1, (32, 32 ) ,imgcv1)
imf = np.float32(imgcv1)/255.0 # float conversion/scale
coeffs = pywt.dwt(imf, "haar") # the dwt
cA = coeffs
#imgout = pywt.dwt(coeffs, "haar")
print(cA)
def zigzag(matrix):
rows=len(matrix)
columns=len(matrix[0])
solution=[[] for i in range(rows+columns-1)]
for i in range(rows):
for j in range(columns):
sum=i+j
if(sum%2 ==0):
solution[sum].insert(0,matrix[i][j])
else:
solution[sum].append(matrix[i][j])
data = (rows*columns)/3
data = round(data)
mtx_zigzag = []
for i in solution:
for j in i:
mtx_zigzag.append(j)
mtxawal = mtx_zigzag[2:26]
# mtxtengah = mtx_zigzag[83:107]
# mtxakhir = mtx_zigzag[191:215]
mtx = mtxawal
# +mtxtengah+mtxakhir
return mtx
hasil_zigzag= zigzag(cA)
print(hasil_zigzag)
zg=[]
zg.append(hasil_zigzag)
citra="tangan {}".format(counter)
file=open('database.csv','a+',newline='')
with file:
write=csv.writer(file)
write.writerows(zg)
the excel /csv data output is like this:
I want the matrix or csv/excel output to be like this:
can you guys help me
I have a binary segmentation map as output from a neural network (niftii format) and want to maintain only the biggest island, to get rid of unwanted false positives.
I am able to achieve this with:
import nibabel as nib
import numpy as np
from scipy.ndimage import label
vol = 'PATH_TO_VOLUME'
elements_in_biggest_island = 0
biggest_index = 0
aNii = nib.load(vol)
a = aNii.get_fdata()
s = np.ones((3,3,3), dtype = 'uint8')
labelled_array, num_features = label(a, structure=s)
for i in range (1, num_features + 1):
tempArray = labelled_array
if (np.count_nonzero(tempArray == i) > elements_in_biggest_island):
elements_in_biggest_island = np.count_nonzero(tempArray == i)
biggest_index = I
print("Biggest Island was at index ", biggest_index, " with a total of ", elements_in_biggest_island, " members.")
labelled_array[labelled_array == biggest_index] = 1.0
labelled_array[labelled_array < biggest_index ] = 0.0
labelled_array[labelled_array > biggest_index] = 0.0
ni_img = nib.Nifti1Image(labelled_array, aNii.affine)
nib.save(ni_img, f'PATH_TO_PROCESSED_VOL')
But the "thresholding" is very inefficient. In another application I work with numpy.where(), which generates a good speedup compared to the shown way of thresholding.
My approach was, to remove the array[array>I] == x lines by:
labelled_array = np.where(labelled_array==biggest_index, 1, 0)
This exact line works perfectly in another application, but here I only get a black 3D volume, which does not work for me.
Is anybody able to point out the mistake, that I have made?
This is a "working example" that does not work. Why does this not run? scipy seems to not work.
i get this error:
File "display_map.py", line 35, in
rot_cw = R.from_quat(keyframe["rot_cw"]).as_matrix()
AttributeError: 'Rotation' object has no attribute 'as_matrix'
please can someone help me me change it. I tried reducing the version of scipy
import msgpack
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
from numpy.linalg import inv
from scipy.spatial.transform import Rotation as R
import open3d as o3d
import sys
if len(sys.argv) < 2:
print(
"ERROR: Please provide path to .msg file. Example usage is; python3 visualize_openvslam_map.py path_to.msg"
)
exit()
with open(sys.argv[1], "rb") as f:
upacked_msg = msgpack.Unpacker(f)
packed_msg = upacked_msg.unpack()
keyfarmes = packed_msg["keyframes"]
landmarks = packed_msg["landmarks"]
# FILL IN KEYFRAME POINTS(ODOMETRY) TO ARRAY
keyframe_points = []
keyframe_points_color = []
for keyframe in keyfarmes.values():
# get conversion from camera to world
trans_cw = np.matrix(keyframe["trans_cw"]).T
rot_cw = R.from_quat(keyframe["rot_cw"]).as_matrix()
# compute conversion from world to camera
rot_wc = rot_cw.T
trans_wc = -rot_wc * trans_cw
keyframe_points.append((trans_wc[0, 0], trans_wc[1, 0], trans_wc[2, 0]))
keyframe_points = np.array(keyframe_points)
keyframe_points_color = np.repeat(np.array([[0., 1., 0.]]),
keyframe_points.shape[0],
axis=0)
# FILL IN LANDMARK POINTS TO ARRAY
landmark_points = []
landmark_points_color = []
for lm in landmarks.values():
landmark_points.append(lm["pos_w"])
landmark_points_color.append([
abs(lm["pos_w"][1]) * 4,
abs(lm["pos_w"][1]) * 2,
abs(lm["pos_w"][1]) * 3
])
landmark_points = np.array(landmark_points)
landmark_points_color = np.array(landmark_points_color)
# CONSTRUCT KEYFRAME(ODOMETRY) FOR VISUALIZTION
keyframe_points_pointcloud = o3d.geometry.PointCloud()
keyframe_points_pointcloud.points = o3d.utility.Vector3dVector(keyframe_points)
keyframe_points_pointcloud.colors = o3d.utility.Vector3dVector(
keyframe_points_color)
# CONSTRUCT LANDMARK POINTCLOUD FOR VISUALIZTION
landmark_points_pointcloud = o3d.geometry.PointCloud()
landmark_points_pointcloud.points = o3d.utility.Vector3dVector(landmark_points)
landmark_points_pointcloud.colors = o3d.utility.Vector3dVector(
landmark_points_color)
# VISULIZE MAP
o3d.visualization.draw_geometries([
keyframe_points_pointcloud, landmark_points_pointcloud,
o3d.geometry.TriangleMesh.create_coordinate_frame()
])
In scipy.spatial.Rotation methods from_dcm, as_dcm were renamed to from_matrix, as_matrix respectively.
I am wondering if there is a way to create a beautiful visualisation (in Python) of something like algorithm which involves graphs.
It would be really nice if there is a way to do that in Python which would help converting each executed logical step of the algorithm's code into a neat live illustration.
While reading about TSP on Wikipedia I found this:
I do it all the time by using individual plots created from matplotlib.
An example procedure is:
create multiple plots and save them as image files
loop over each saved image file and read them using opencv
use opencv to compile all image files into a single video file.
Here is some simplified example code
import cv2
import os
import matplotlib.pyplot as plt
# create a single plot
plt.plot([1,2,3], [3, 7, 11])
# save plot as an image
plt.savefig(plot_directory\plot_name.jpg, format='jpg', dpi=250)
plt.show()
def create_video(image_folder, video_name, fps=8, reverse=False):
"""Create video out of images saved in a folder."""
images = [img for img in os.listdir(image_folder) if img.endswith('.jpg')]
if reverse: images = images[::-1]
frame = cv2.imread(os.path.join(image_folder, images[0]))
height, width, layers = frame.shape
video = cv2.VideoWriter(video_name, -1, fps, (width,height))
for image in images:
video.write(cv2.imread(os.path.join(image_folder, image)))
cv2.destroyAllWindows()
video.release()
# use opencv to read all images in a directory and compile them into a video
create_video('plot_directory', 'my_video_name.avi')
In the create_video function, I added options to reverse the frame order and set frames per second (fps).
This video on Youtube was created using exactly this method.
To apply to your sample code, try putting all your plotting functions inside your for loop. This should produce plots each tome you iterate over an edge. Then each time a plot is generated, you can save that plot to file. Something like this:
import random
from itertools import combinations
from math import sqrt
import itertools
from _collections import OrderedDict
import networkx as nx
import numpy as np
from matplotlib import pyplot as plt
random.seed(42)
n_points = 10
def dist(p1, p2):
return sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
points = [(random.random(), random.random()) for _ in range(n_points)]
named_points = {i: j for i, j in zip(itertools.count(), points)}
weighted_edges = dict()
tree_id = [None] * n_points
min_tree = []
for v1, v2 in combinations(named_points.values(), 2):
d = dist(v1, v2)
weighted_edges.update({d: ((list(named_points.keys())[list(named_points.values()).index(v1)]),
(list(named_points.keys())[list(named_points.values()).index(v2)]))
}
)
for i in range(n_points):
tree_id[i] = i
sorted_edges = OrderedDict(sorted(weighted_edges.items(), key=lambda t: t[0]))
list_edges = sorted_edges.values()
for edge in list_edges:
if tree_id[edge[0]] != tree_id[edge[1]]:
min_tree.append(edge)
old_id = tree_id[edge[0]]
new_id = tree_id[edge[1]]
for j in range(n_points):
if tree_id[j] == old_id:
tree_id[j] = new_id
print(min_tree)
G = nx.Graph()
G.add_nodes_from(range(n_points))
G.add_edges_from(list_edges)
green_edges = min_tree
G = nx.Graph()
G.add_nodes_from(range(n_points))
G.add_edges_from(list_edges)
edge_colors = ['black' if not edge in green_edges else 'red' for edge in G.edges()]
pos = nx.spiral_layout(G)
G2 = nx.Graph()
G2.add_nodes_from(range(n_points))
G2.add_edges_from(min_tree)
pos2 = nx.spiral_layout(G2)
plt.figure(1)
nx.draw(G, pos, node_size=700, edge_color=edge_colors, edge_cmap=plt.cm.Reds, with_labels = True)
plt.figure(2)
nx.draw(G2, pos2, node_size=700, edge_color='green', edge_cmap=plt.cm.Reds, with_labels = True)
plt.show()
I am trying to plot a very big file (~5 GB) using python and matplotlib. I am able to load the whole file in memory (the total available in the machine is 16 GB) but when I plot it using simple imshow I get a segmentation fault. This is most probable to the ulimit which I have set to 15000 but I cannot set higher. I have come to the conclusion that I need to plot my array in batches and therefore made a simple code to do that. My main isue is that when I plot a batch of the big array the x coordinates start always from 0 and there is no way I can overlay the images to create a final big one. If you have any suggestion please let me know. Also I am not able to install new packages like "Image" on this machine due to administrative rights. Here is a sample of the code that reads the first 12 lines of my array and make 3 plots.
import os
import sys
import scipy
import numpy as np
import pylab as pl
import matplotlib as mpl
import matplotlib.cm as cm
from optparse import OptionParser
from scipy import fftpack
from scipy.fftpack import *
from cmath import *
from pylab import *
import pp
import fileinput
import matplotlib.pylab as plt
import pickle
def readalllines(file1,rows,freqs):
file = open(file1,'r')
sizer = int(rows*freqs)
i = 0
q = np.zeros(sizer,'float')
for i in range(rows*freqs):
s =file.readline()
s = s.split()
#print s[4],q[i]
q[i] = float(s[4])
if i%262144 == 0:
print '\r ',int(i*100.0/(337*262144)),' percent complete',
i += 1
file.close()
return q
parser = OptionParser()
parser.add_option('-f',dest="filename",help="Read dynamic spectrum from FILE",metavar="FILE")
parser.add_option('-t',dest="dtime",help="The time integration used in seconds, default 10",default=10)
parser.add_option('-n',dest="dfreq",help="The bandwidth of each frequency channel in Hz",default=11.92092896)
parser.add_option('-w',dest="reduce",help="The chuncker divider in frequency channels, integer default 16",default=16)
(opts,args) = parser.parse_args()
rows=12
freqs = 262144
file1 = opts.filename
s = readalllines(file1,rows,freqs)
s = np.reshape(s,(rows,freqs))
s = s.T
print s.shape
#raw_input()
#s_shift = scipy.fftpack.fftshift(s)
#fig = plt.figure()
#fig.patch.set_alpha(0.0)
#axes = plt.axes()
#axes.patch.set_alpha(0.0)
###plt.ylim(0,8)
plt.ion()
i = 0
for o in range(0,rows,4):
fig = plt.figure()
#plt.clf()
plt.imshow(s[:,o:o+4],interpolation='nearest',aspect='auto', cmap=cm.gray_r, origin='lower')
if o == 0:
axis([0,rows,0,freqs])
fdf, fdff = xticks()
print fdf
xticks(fdf+o)
print xticks()
#axis([o,o+4,0,freqs])
plt.draw()
#w, h = fig.canvas.get_width_height()
#buf = np.fromstring(fig.canvas.tostring_argb(), dtype=np.uint8)
#buf.shape = (w,h,4)
#buf = np.rol(buf, 3, axis=2)
#w,h,_ = buf.shape
#img = Image.fromstring("RGBA", (w,h),buf.tostring())
#if prev:
# prev.paste(img)
# del prev
#prev = img
i += 1
pl.colorbar()
pl.show()
If you plot any array with more than ~2k pixels across something in your graphics chain will down sample the image in some way to display it on your monitor. I would recommend down sampling in a controlled way, something like
data = convert_raw_data_to_fft(args) # make sure data is row major
def ds_decimate(row,step = 100):
return row[::step]
def ds_sum(row,step):
return np.sum(row[:step*(len(row)//step)].reshape(-1,step),1)
# as per suggestion from tom10 in comments
def ds_max(row,step):
return np.max(row[:step*(len(row)//step)].reshape(-1,step),1)
data_plotable = [ds_sum(d) for d in data] # plug in which ever function you want
or interpolation.
Matplotlib is pretty memory-inefficient when plotting images. It creates several full-resolution intermediate arrays, which is probably why your program is crashing.
One solution is to downsample the image before feeding it into matplotlib, as #tcaswell suggests.
I also wrote some wrapper code to do this downsampling automatically, based on your screen resolution. It's at https://github.com/ChrisBeaumont/mpl-modest-image, if it's useful. It also has the advantage that the image is resampled on the fly, so you can still pan and zoom without sacrificing resolution where you need it.
I think you're just missing the extent=(left, right, bottom, top) keyword argument in plt.imshow.
x = np.random.randn(2, 10)
y = np.ones((4, 10))
x[0] = 0 # To make it clear which side is up, etc
y[0] = -1
plt.imshow(x, extent=(0, 10, 0, 2))
plt.imshow(y, extent=(0, 10, 2, 6))
# This is necessary, else the plot gets scaled and only shows the last array
plt.ylim(0, 6)
plt.colorbar()
plt.show()