def add_blob(obj, src_q=None, v=None, scale=0.001, style="star", distance=1.0): angle_rs = { "diamond": [(i, 1) for i in range(0, 450, 90)], "star": [(i, [1, 0.5][((i / 36) & 1)]) for i in range(0, 396, 36)], "triangle": [(i, 1) for i in range(0, 450, 120)], "inv_triangle": [(i, 1) for i in range(60, 450, 120)], } if v is not None: cxyz = v.coords dv = vector_z if (cxyz[0] == 0) and (cxyz[0] == 0): dv = vector_y src_q = quaternion().lookat(v, dv) pass else: cxyz = src_q.rotate_vector(vector((0, 0, distance))).coords pass lxyz = None for (angle, r) in angle_rs[style]: vector_z_sc = vector((0, scale * r, distance)) xyz = (src_q * quaternion().from_euler( roll=angle, degrees=1)).rotate_vector(vector_z_sc).coords if lxyz is not None: obj.add_triangle([cxyz, lxyz, xyz], [(0, 0)] * 3) pass lxyz = xyz pass pass
def quaternion_average(qs): vf = gjslib_c.vector(length=3) vu = gjslib_c.vector(length=3) for q in qs: vf += q.rotate_vector(vector_z) vu += q.rotate_vector(vector_x) pass return gjslib_c.quaternion().lookat(vf, vu)
def build_add_projected_image_mesh(obj,camera,src_w,src_h,n=32,z=8): triangles = [] for x in range(n): for y in range(n): x0 = (x/float(n)-0.5) x1 = ((x+1)/float(n)-0.5) y0 = src_h*(y/float(n)-0.5) y1 = src_h*((y+1)/float(n)-0.5) triangles.append( ( (x0,y0), (x1,y0), (x0,y1) ) ) triangles.append( ( (x1,y1), (x1,y0), (x0,y1) ) ) pass pass for triangle in triangles: src_xyzs = [] src_uvs = [] for xy in triangle: # points for 'src' mesh - also uses 'src' as the image texture, hence needs uv in 'src' terms src_xy = (xy[0]*src_w, xy[1]*src_w) src_q = camera.orientation_of_xy(src_xy) xyz = src_q.rotate_vector(gjslib_c.vector((0,0,z))) src_xyzs.append(xyz.coords) src_uvs.append(((xy[0]+1.0/2)/1,(1.0/2+xy[1]/src_h)/1)) pass obj.add_triangle( xyz_list = src_xyzs, uv_list = src_uvs ) pass return obj
def add_blob(obj, src_q, scale=0.001, style="star"): angle_rs = {"diamond": [(i,1) for i in range(0,450,90)], "star": [(i,[1,0.5][((i/36)&1)]) for i in range(0,396,36)], "triangle": [(i,1) for i in range(0,450,120)], "inv_triangle": [(i,1) for i in range(60,450,120)], } cxyz= src_q.rotate_vector(gjslib_c.vector((0,0,0.8))).coords lxyz = None for (angle,r) in angle_rs[style]: vector_z_sc = gjslib_c.vector((0,scale*r,0.8)) xyz = (src_q*gjslib_c.quaternion().from_euler(roll=angle,degrees=1)).rotate_vector(vector_z_sc).coords if lxyz is not None: obj.add_triangle([cxyz,lxyz,xyz],[(0,0)]*3) pass lxyz = xyz pass pass
class c_octahedron(c_polyhedron): vertices = ( vector((1, 0, 0)), vector((-1, 0, 0)), vector((0, 1, 0)), vector((0, -1, 0)), vector((0, 0, 1)), vector((0, 0, -1)), ) edges = ((1, 3), (1, 4), (1, 5), (1, 6), (2, 3), (2, 4), (2, 5), (2, 6), (3, 5), (5, 4), (4, 6), (6, 3)) faces = ((1, 3, 5), (1, 5, 4), (1, 4, 6), (1, 6, 3), (3, 2, 5), (5, 2, 4), (4, 2, 6), (6, 2, 3)) faces = c_polyhedron.faces_from_vertices(faces, vertices, edges) pass
def add_shape_subdivision(shape, sd, hue, fill=False, color_by_area=True): f = shape.subface(sd) center = vector((0, 0, 0)) for v in f.corners: center += v pass center.scale(1 / 3.0) center_displacement = 1 / (1.0 - center.modulus()) rel_area = f.area() * (4**len(sd)) / shape.subface(0).area() / 4 if color_by_area: if rel_area < 0: rel_area = -1 / rel_area hue = 120 * (1 + rel_area / 2) obj = c_view_sphere_obj( has_surface=True, color=rgb_of_hue(hue), selectable=True, note="%d : %s : %f : %f : %f" % (len(sd), str(sd), f.area(), rel_area, center_displacement)) if fill: obj.add_triangle(vector_coord_list(f.corners), [(0, 0)] * 3) return obj n = 0 for v in f.corners: add_blob(obj, v=v, style=["triangle", "diamond", "star"][n], scale=0.03 / len(sd)) n += 1 pass for (d, g) in f.edge_dirns: obj.add_line(vector_coord_list(g.interpolate())) obj.add_line((g.p0.coords, g.p1.coords)) pass return obj
#!/usr/bin/env python # PYTHONPATH=`pwd`/../python:$PYTHONPATH ./view_camera.py # PYTHONPATH=`pwd`/../python:`pwd`/..:`pwd`/gjslib/../python::`pwd`/../../gjslib/python:$PYTHONPATH ./view_camera.py #a Imports from gjslib.graphics import opengl_app, opengl_utils, opengl_obj import math from OpenGL.GLUT import * from OpenGL.GLU import * from OpenGL.GL import * import gjslib_c from filters import * vector_z = gjslib_c.vector(vector=(0,0,1)) gjslib_c.lens_projection.add_named_polynomial("canon_20_35_rebel2Ti_20", canon_20_35_rebel2Ti_20_polynomial[0], canon_20_35_rebel2Ti_20_polynomial[1]) #a Classes #c c_view_obj class c_view_obj(opengl_app.c_opengl_camera_app): #f __init__ def __init__(self, obj, **kwargs): opengl_app.c_opengl_camera_app.__init__(self, **kwargs) self.objects = obj self.xxx = 0.0 self.yyy = 0.0 self.window_title = "Viewing object" self.selection=None self.camera["position"] = [0,0,0] self.zNear=0.2 #self.camera["facing"] = quaternion.pitch(90,degrees=True) * self.camera["facing"] from gjslib.math.quaternion import quaternion
class c_icosahedron(c_polyhedron): """ A 20mm lens on a 22.3mm sensor is 58 degree horizontal, 40 degree vertical; this is about 1/20th of a sphere At 30Mpixel there would be 600Mpixel for the sphere subdivision of length 5 (i.e. each face subdivided 4 times) has a center that is about .1% away from 1.0 length and each subdivision gets it a factor of 4 closer subdivison of length 8 closest to a vertex has 0.0014% (1 part in 70,000) subdivison of length 8 closest to center has 0.0018% (1 part in 56,000) The earth has a radius of 6,000km; so 1 part in 70,000 is about 80m Subdivision length 8 is each face divided 7 times, so 4^7 faces per triangle, or 2^14 = 16384 faces - total of 320k faces for the sphere Each edge is 1.1755 long, or 7,053km So subdivision length 8 is divide each side by 128, or 55km Subdivision length 6 is 80k faces for the sphere, and a part in 4,500 (at vertex) or 3,500 (center of face) This is an error of 2km at the center. Each edge is 1.1755 long, or 7,053km So subdivision length 6 is divide each side by 32, or 221km At 80k faces, with 600Mpixels for a sphere, that is 8k pixels per face - as half of a square, that is 128 pixels per side of each face At 600Mpixels that is 30Mpixels per triangular face, 60Mpixels per face pair - or 8kx8k images The base image could be 10Mpixels - or 1Mpixel per face pair, or 1k by 1k for each face edge, 32 pixels per each side of each face """ gr = (math.sqrt(5) - 1) / 2 vertices = ( vector((1, 0, gr)), vector((1, 0, -gr)), vector((-1, 0, gr)), vector((-1, 0, -gr)), vector((gr, 1, 0)), vector((-gr, 1, 0)), vector((gr, -1, 0)), vector((-gr, -1, 0)), vector((0, gr, 1)), vector((0, -gr, 1)), vector((0, gr, -1)), vector((0, -gr, -1)), ) edges = ( (1, 2), (1, 5), (1, 7), (1, 9), (1, 10), # 1 top (2, 5), (5, 9), (9, 10), (10, 7), (7, 2), # 6 ring 2,5,9,10,7 (4, 3), (4, 6), (4, 8), (4, 11), (4, 12), # 11 bottom (3, 6), (6, 11), (11, 12), (12, 8), (8, 3), # 16 ring 11,6,3,8,12 (12, 2), (2, 11), (11, 5), (5, 6), (6, 9), (9, 3), (3, 10), (10, 8), (8, 7), (7, 12), ) faces = ( (1, 2, 5), (1, 5, 9), (1, 9, 10), (1, 10, 7), (1, 7, 2), (4, 3, 6), (4, 6, 11), (4, 11, 12), (4, 12, 8), (4, 8, 3), (2, 11, 5), (11, 6, 5), (5, 6, 9), (6, 3, 9), (9, 3, 10), (3, 8, 10), (10, 8, 7), (8, 12, 7), (7, 12, 2), (12, 11, 2), ) faces = c_polyhedron.faces_from_vertices(faces, vertices, edges) pass
class c_tetrahedron(c_polyhedron): vertices = (vector((1, 1, 1)), vector((1, -1, -1)), vector( (-1, 1, -1)), vector((-1, -1, 1))) edges = ((1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)) faces = ((1, 2, 3), (1, 4, 2), (1, 3, 4), (2, 4, 3)) faces = c_polyhedron.faces_from_vertices(faces, vertices, edges)
#!/usr/bin/env python # PYTHONPATH=`pwd`/../python:$PYTHONPATH ./view_camera.py # PYTHONPATH=`pwd`/../python:`pwd`/..:`pwd`/gjslib/../python::`pwd`/../../gjslib/python:$PYTHONPATH ./view_sphere.py #a Imports from gjslib.graphics import opengl_app, opengl_utils, opengl_obj import math from OpenGL.GLUT import * from OpenGL.GLU import * from OpenGL.GL import * import gjslib_c from gjslib_c import vector, quaternion, lens_projection from filters import * vector_x = vector((1, 0, 0)) vector_y = vector((0, 1, 0)) vector_z = vector((0, 0, 1)) lens_projection.add_named_polynomial("canon_20_35_rebel2Ti_20", canon_20_35_rebel2Ti_20_polynomial[0], canon_20_35_rebel2Ti_20_polynomial[1]) #a Classes #c spherical_angle def spherical_angle(p, p0, p1): """ A spherical angle is formed from three points on the sphere, p, p0 and p1 Two great circles (p,p0) and (p,p1) have an angle between them (the rotation anticlockwise about p that it takes to move the p,p0 great circle p,p1).
def quaternion_image_correlate(ipqm, images, focal_length=50.0, accuracy="80pix35", max_n=10, num_proj=2): print "Quaternion_Image_Correlate" orientations_to_use = ( gjslib_c.quaternion().from_euler(yaw=-12.0, degrees=1), gjslib_c.quaternion().from_euler(yaw=+12.0, degrees=1), ) if num_proj == 1: orientations_to_use = (gjslib_c.quaternion().from_euler(yaw=0, degrees=1), ) if num_proj > 2: src_img_lp_to = gjslib_c.lens_projection(width=2.0, height=2.0, frame_width=36.0, focal_length=15, lens_type="rectilinear") dst_img_lp_to = gjslib_c.lens_projection(width=2.0, height=2.0, frame_width=36.0, focal_length=15, lens_type="rectilinear") src_img_lp_to.orient(gjslib_c.quaternion(1)) dst_img_lp_to.orient(gjslib_c.quaternion(1)) if not ipqm.overlap_projections((images[0], images[1]), (src_img_lp_to, dst_img_lp_to), verbose=False): raise Exception, "Failed to organize projections" print "Focal length now ", src_img_lp_to.focal_length, "centered on", src_img_lp_to.orientation.rotate_vector( vector_z) print "For num_proj=4, want to double the focal_length and center on quadrants" vs = [] for i in range(4): dxy = ((-1, -1), (1, -1), (1, 1), (-1, 1))[i] vs.append( (src_img_lp_to.orientation_of_xy(dxy).rotate_vector(vector_z), src_img_lp_to.orientation_of_xy(dxy).rotate_vector(vector_x))) pass orientations_to_use = [] for factors in ((9, 3, 1, 3), (3, 9, 3, 1), (1, 3, 9, 3), (3, 1, 3, 9)): vf = gjslib_c.vector(vector=(0, 0, 0)) vu = gjslib_c.vector(vector=(0, 0, 0)) for i in range(4): vf += vs[i][0].copy().scale(factors[i]) vu += vs[i][1].copy().scale(factors[i]) pass orientations_to_use.append(gjslib_c.quaternion().lookat(vf, vu)) pass focal_length = src_img_lp_to.focal_length * 2 pass ci0 = ipqm.camera_images[images[0]] ci1 = ipqm.camera_images[images[1]] ipqm.qic = gjslib_c.quaternion_image_correlator() ipqm.qic.min_cos_angle_src_q = min_cos_seps_same_pt[accuracy] ipqm.qic.min_cos_angle_tgt_q = min_cos_seps_same_pt[accuracy] ipqm.qic.min_cos_sep_score = min_cos_seps_for_score[ accuracy] # tgt point must be within this separation for any match of src->tgt to count ipqm.qic.max_q_dist_score = max_q_dists_for_score[ accuracy] # src/src/tgt/tgt orientation must be within this for a point for src->tgt for initial_orientation in orientations_to_use: src_img_lp_to = gjslib_c.lens_projection(width=2.0, height=2.0, frame_width=36.0, focal_length=focal_length, lens_type="rectilinear") dst_img_lp_to = gjslib_c.lens_projection(width=2.0, height=2.0, frame_width=36.0, focal_length=focal_length, lens_type="rectilinear") src_img_lp_to.orient(initial_orientation) dst_img_lp_to.orient(initial_orientation) projections = (src_img_lp_to, dst_img_lp_to) if not ipqm.overlap_projections((images[0], images[1]), (src_img_lp_to, dst_img_lp_to)): continue print "Using src projection focal length", src_img_lp_to.focal_length, "centered on", ( src_img_lp_to.orientation).rotate_vector(vector_z) ipqm.find_matches((images[0], images[1]), projections=projections) pass ipqm.qic.create_mappings() best_matches = ipqm.find_best_target_matches_qic( max_q_dist=max_q_dists[accuracy], min_q_dist=min_q_dists[accuracy] / 10.0, min_cos_sep=min_cos_seps[accuracy], min_cos_sep_score=min_cos_seps[accuracy], max_q_dist_score=min_q_dists[accuracy], ) print ipqm.times() #b Do clusters def cmp_matches(x, y): return cmp(y.max_distance, x.max_distance) if x.max_distance / len(x.mappings) < y.max_distance / len(y.mappings): return -1 return 1 best_matches.sort(cmp=lambda x, y: cmp(y.max_distance, x.max_distance)) print "Best matches for whole image" n = len(best_matches) if n > max_n: n = max_n best_matches = best_matches[:n] for bm in best_matches: bm.calculate(ipqm.qic) pass return best_matches
#!/usr/bin/env python # # PYTHONPATH=`pwd`/../python:`pwd`/..:`pwd`/gjslib/../python::`pwd`/../../gjslib/python:$PYTHONPATH ./qic_match.py # #a Imports import OpenGL.GLUT import OpenGL.GL import gjslib_c import math import sys from filters import * img_png_n = 0 vector_z = gjslib_c.vector(vector=(0, 0, 1)) vector_x = gjslib_c.vector(vector=(1, 0, 0)) #a Basic lens setup gjslib_c.lens_projection.add_named_polynomial( "canon_20_35_rebel2Ti_20", canon_20_35_rebel2Ti_20_polynomial[0], canon_20_35_rebel2Ti_20_polynomial[1]) #a Cos seps etc wobbles = [] r = gjslib_c.quaternion().from_euler(roll=0.303, degrees=1) p = gjslib_c.quaternion().from_euler(pitch=0.303, degrees=1) y = gjslib_c.quaternion().from_euler(yaw=0.303, degrees=1) for i in range(8): q = gjslib_c.quaternion(1) if i & 1: q = r * q else: q = ~r * q if i & 2: q = p * q else: q = ~p * q