Related
I'm trying to import these on Jupyter, however I got an error when I run these code that say ModuleNotFoundError: No module named 'anna_phog'. I have another python file named as 'anna_phog'. How do I fix this?
below is 'anna_phog_demo.py' where I got the error
from anna_phog import anna_phog
import imageio
import matplotlib.pyplot as plt
image_path = "image_0058.jpg"
S = 8
angle = 360
Level = 3
roi = [1,225,1,300]
save=True
Image = imageio.imread(image_path)
p = anna_phog(Image, bin, angle, Level, roi)
print("P: \n{}".format(p))
print(len(p), type(p))
And below is the 'anna_phog.py' code
import numpy as np
import imageio
import cv2
import matplotlib.pyplot as plt
def anna_phog(Img, bin, angle, L, roi):
if Img.shape[2] == 3:
G = cv2.cvtColor(Img, cv2.COLOR_BGR2GRAY)
else:
G = Img
if np.sum(G) > 100:
# apply automatic Canny edge detection using the computed median
sigma = 0.33
v = np.median(G)
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
E = cv2.Canny(G,lower,upper) #high and low treshold
GradientX, GradientY = np.gradient(G)
GradientYY = np.gradient(GradientY, axis=1)
Gr = np.sqrt(np.square(GradientX)+np.square(GradientY))
index = GradientX == 0
GradientX[index] = 1e-5 #maybe another value
YX = GradientY*GradientX
if angle == 180: A = ((np.arctan(YX)+(np.pi/2))*180)/np.pi
if angle == 360: A = ((np.arctan2(GradientY,GradientX)+np.pi)*180)/np.pi
bh, bv = anna_BinMatrix(A,E,Gr,angle,bin)
else:
bh = np.zeros(Img.shape)
bv = np.zeros(Img.shape)
bh_roi = bh[roi[0]:roi[1], roi[2]:roi[3]]
bv_roi = bv[roi[0]:roi[1], roi[2]:roi[3]]
p = anna_PhogDescriptor(bh_roi,bv_roi,L,bin)
return p
def anna_BinMatrix(A,E,G,angle,bin):
n, contorns = cv2.connectedComponents(E, connectivity=8)
X = E.shape[1]
Y = E.shape[0]
bm = np.zeros(shape=(Y,X))
bv = np.zeros(shape=(Y,X))
nAngle = angle/bin
for i in range(n):
posY, posX = np.where(contorns==i)
for j in range(posY.shape[0]):
pos_x = posX[j]
pos_y = posY[j]
b = np.ceil(A[pos_y,pos_x]/nAngle)
if b==0: bin=1
if G[pos_y,pos_x]>0:
bm[pos_y,pos_x] = b
bv[pos_y,pos_x] = G[pos_y,pos_x]
return (bm, bv)
def anna_PhogDescriptor(bh,bv,L,bin):
p = np.array([])
#level 0
for b in range(bin):
ind = bh==b
p = np.append(p, np.sum(bv[ind]))
#higher levels
for l in range(1, L+1):
x = int(np.trunc(bh.shape[1]/(2**l)))
y = int(np.trunc(bh.shape[0]/(2**l)))
for xx in range(0, bh.shape[1]-x+1, x):
for yy in range(0, bh.shape[0]-y+1, y):
print(l)
bh_cella = bh[yy:yy+y, xx:xx+x]
bv_cella = bv[yy:yy+y, xx:xx+x]
for b in range(bin):
ind = bh_cella==b
p = np.append(p, np.sum(bv_cella[ind], axis=0))
if np.sum(p)!=0:
p = p/np.sum(p)
return p
Below is the screenshot of the folder where I put these file
folder path
I am very new to coding and decided to start with a 3D engine in python. I followed OLC's tutorial and adapted it for python. However, my translation matrix doesn't seem to be affecting how the model is rendered. Any advice at all, from code improvements, to telling me how bad I am would be much appreciated.
I have tried to re-do the vector multiplication in all sorts of ways, and all kinds of reformatting and re-trying, but I am not even sure what I am looking for in this case. Any help would be much appreciated
As I am new, I apologize for any poor etiquette I may have done on this site.
import math, numpy as np, pygame, sys, os, random, string
from pygame.locals import *
pygame.init()
width,height = 1600,900;cx,cy = width//2,height//2
screen = pygame.display.set_mode((width,height))
clock = pygame.time.Clock()
font = pygame.font.SysFont("Arial", 18)
pygame.display.set_caption('3D Graphics')
def loadObj(filename):
tris = []
verts = []
try:
fp = open(filename, "r")
except:
print("File: "+filename+" not found")
sys.exit(1)
for line in fp:
if line.startswith('#'): continue
values = line.split()
if not values: continue
if values[0] == 'v':
#v = vec3(float(values[1]), float(values[2]), float(values[3]))
#verts.append(vec3(int(values[1]), int(values[2]), int(values[3])))
verts.append(vec3(float(values[1]), float(values[2]), float(values[3]), 0 ))
#verts.append(v)
elif values[0] == 'f':
p = []
for v in values[1:]:
w = v.split("/")
p.append(int(w[0]))
#print(p)
#print(verts[-185])
triTemp = triangle(verts[p[0] - 1], verts[p[1] - 1], verts[p[2]- 1])
tris.append(triTemp)
fp.close()
return tris
class vec3(): #Possibly Obsolete
__slots__ = ['x','y','z','w']
def __init__(self, x, y, z, w):
self.x = x
self.y = y
self.z = z
self.w = w
class triangle():
__slots__ = ['vec1','vec2','vec3']
def __init__(self, vec1, vec2, vec3):
self.vec1 = vec1
self.vec2 = vec2
self.vec3 = vec3
def matrixMakeTranslation(x, y, z):
matrix = np.zeros((4,4))
matrix[0,0] = 1.0
matrix[1,1] = 1.0
matrix[2,2] = 1.0
matrix[3,3] = 1.0
matrix[3,0] = x
matrix[3,1] = y
matrix[3,2] = z
return matrix
def Matrix_MakeRotationX(fAngleRad):
matrix = np.zeros((4,4))
matrix[0,0] = 1.0
matrix[1,1] = (math.cos(fAngleRad * 0.5))
matrix[1,2] = (math.sin(fAngleRad * 0.5))
matrix[2,1] = (-math.sin(fAngleRad * 0.5))
matrix[2,2] = (math.cos(fAngleRad * 0.5))
matrix[3,3] = 1.0
return matrix
def Matrix_MakeRotationZ(fAngleRad):
matrix = np.zeros((4,4))
matrix[0,0] = (math.cos(fAngleRad))
matrix[0,1] = (math.sin(fAngleRad))
matrix[1,0] = (-math.sin(fAngleRad))
matrix[1,1] = (math.cos(fAngleRad))
matrix[2,2] = 1.0
matrix[3,3] = 1.0
return matrix
fNear = float(0.1) #Create the Projection Matrix
fFar = float(1000.0)
fFov = float(90.0)
fAspectRatio = float(height/width)
fFovRad = 1/math.tan(fFov * 0.5 / 180 * math.pi)
projectionMatrix = np.zeros((4,4))
projectionMatrix[0,0] = fAspectRatio * fFovRad
projectionMatrix[1,1] = fFovRad
projectionMatrix[2,2] = fFar / (fFar - fNear)
projectionMatrix[3,2] = float((-fFar * fNear) / (fFar - fNear))
projectionMatrix[2,3] = 1.0
projectionMatrix[3,3] = 0.0
meshname = "teapot.obj" #Load the mesh
tris = loadObj(meshname)
vCamera = np.array([0,0,0,0])
fAngleRad = 0
colour = (255,255,255)
colour2 = (0,0,0)
triProjected = triangle(np.array([0,0,0,0]),np.array([0,0,0,0]),np.array([0,0,0,0])) #These are used later
triTranslalted = triangle(np.array([0,0,0,0]),np.array([0,0,0,0]),np.array([0,0,0,0]))
triTransformed= triangle(np.array([0,0,0,0]),np.array([0,0,0,0]),np.array([0,0,0,0]))
while True: #Begin Loop
for event in pygame.event.get(): #Quit
if event.type == pygame.QUIT: pygame.quit(); sys.exit()
dt = clock.tick()/1000
pygame.display.set_caption('3D Graphics - FPS: %.2f'%int(dt))
print("fps:", clock.get_fps()) #Framerate and caption
pygame.display.update()
screen.fill((0,0,0))
fAngleRad += 0.1
matRotZ = Matrix_MakeRotationZ(fAngleRad * 0.5) #Set up matricies
matRotX = Matrix_MakeRotationX(fAngleRad)
matTrans = matrixMakeTranslation(0.0,0.0,50.0)
matWorld = np.identity(4)
matWorld = matRotZ # matRotX
matWorld = matWorld # matTrans #Seems to be broken. idk why.
for i in tris: #For triangle in all triangles
reDo1 = np.array([i.vec1.x, i.vec1.y, i.vec1.z, i.vec1.w])
reDo2 = np.array([i.vec2.x, i.vec2.y, i.vec2.z, i.vec2.w])
reDo3 = np.array([i.vec3.x, i.vec3.y, i.vec3.z, i.vec3.w])
triTransformed.vec1 = np.matmul(matWorld, reDo1)
triTransformed.vec2 = np.matmul(matWorld, reDo2)
triTransformed.vec3 = np.matmul(matWorld, reDo3)
triProjected.vec1 = np.matmul(projectionMatrix, triTransformed.vec1)
triProjected.vec2 = np.matmul(projectionMatrix, triTransformed.vec2)
triProjected.vec3 = np.matmul(projectionMatrix, triTransformed.vec3)
#Scale Into View
triProjected.vec1[0] += 1.0
triProjected.vec1[1] += 1.0
triProjected.vec2[0] += 1.0
triProjected.vec2[1] += 1.0
triProjected.vec3[0] += 1.0
triProjected.vec3[1] += 1.0
triProjected.vec1[0] *= 0.5 * width
triProjected.vec1[1] *= 0.5 * height
triProjected.vec2[0] *= 0.5 * width
triProjected.vec2[1] *= 0.5 * height
triProjected.vec3[0] *= 0.5 * width
triProjected.vec3[1] *= 0.5 * height
pygame.draw.polygon(screen, colour, [(triProjected.vec1[0], triProjected.vec1[1]),(triProjected.vec2[0], triProjected.vec2[1]),(triProjected.vec3[0], triProjected.vec3[1])])
You are using Homogenious Coordinates to represent the vertices of your model. So the W component must be 1.
When you load your model you are setting W to 0.
verts.append(vec3(float(values[1]), float(values[2]), float(values[3]), 0 ))
By setting W=0 you are creating a Homogenious Vector (a.k.a "point at infinity" or "ideal point") and by setting W=1 you are creating a Homogeneous Point.
Points can be translated but vectors cannot.
https://en.m.wikipedia.org/wiki/Homogeneous_coordinates
Here's the error:
File "/Users/KarenLee/Desktop/temp/worldmodel.py", line 76, in update_on_time
obj = VeinAction(entity, image_store)
NameError: global name 'VeinAction' is not defined
And here is my code (this is in the file "actions.py"):
import entities
import worldmodel
import pygame
import math
import random
import point
import image_store
BLOB_RATE_SCALE = 4
BLOB_ANIMATION_RATE_SCALE = 50
BLOB_ANIMATION_MIN = 1
BLOB_ANIMATION_MAX = 3
FREEZE_ANIMATION_RATE = 100
FREEZE_STEPS = 4
ORE_CORRUPT_MIN = 20000
ORE_CORRUPT_MAX = 30000
QUAKE_STEPS = 10
QUAKE_DURATION = 1100
QUAKE_ANIMATION_RATE = 100
VEIN_SPAWN_DELAY = 500
VEIN_RATE_MIN = 8000
VEIN_RATE_MAX = 17000
WYVERN_RATE_MIN = 200
WYVERN_RATE_MAX = 600
WYVERN_ANIMATION_RATE = 100
class VeinAction:
def __init__(self, entity, image_store):
self.entity = entity
self.image_store = image_store
def vein_action(self, world, action, ticks):
entity = self.entity
open_pt = find_open_around(world, entities.get_position(entity),
entities.get_resource_distance(entity))
if open_pt:
ore = create_ore(world,
"ore - " + entities.get_name(entity) + " - " + str(ticks),
open_pt, ticks, action.image_store)
worldmodel.add_entity(world, ore)
tiles = [open_pt]
else:
tiles = []
schedule_action(world, entity, VeinAction(entity, action.image_store),
ticks + entities.get_rate(entity))
return tiles
def vein_take_action(self, world, action, ticks):
entities.remove_pending_action(self.entity, action)
if isinstance(action, VeinAction):
return self.vein_action(world, action, ticks)
And this is in the file "worldmodel.py":
import entities
import pygame
import ordered_list
import actions
import occ_grid
import point
class WorldModel:
def __init__(self, num_rows, num_cols, background):
self.background = occ_grid.Grid(num_cols, num_rows, background)
self.num_rows = num_rows
self.num_cols = num_cols
self.occupancy = occ_grid.Grid(num_cols, num_rows, None)
self.entities = []
self.action_queue = ordered_list.OrderedList()
def update_on_time(world, ticks):
tiles = []
next = world.action_queue.head()
obj = VeinAction(entity, image_store)
while next and next.ord < ticks:
world.action_queue.pop()
tiles.extend(obj.vein_take_action(world, next.item, ticks))
tiles.extend(actions.take_action(world, next.item, ticks))
next = world.action_queue.head()
return tiles
The error message comes from the update_on_time function in "worldmodel.py". I thought that this was how you would call a method from a class in a different file in a function, but it doesn't work! What is the correct way to do this? Or, is it possible to do this? Thanks in advance.
You imported the module actions which contains the class VeinAction. However, Python does not know this. You need to tell Python where VeinAction is located by adding actions. before it:
obj = actions.VeinAction(entity, image_store)
That, or you could import VeinAction directly:
from actions import VeinAction
Either way, you need to make sure that Python can find the class VeinAction.
Running this code: Python simulation to calculate potential difference of a rod
Setup Statements:
from __future__ import division
from visual import *
from visual.graph import *
scene = display(x=0, y=0, width=600, height = 600)
graph = gdisplay(x=600, y=0, width=400, height=300)
Main body of code:
#Objects
Vgraph=gcurve(color=color.cyan)
marker = sphere(pos=vector(0,.15,0), radius=.05, color=color.red)
marker.v = vector(0,.5,0)
#Constants
e = 1.6e-19
oofpez = 9e9
scalefactor = 8e-3
dt = 0.001
#Initial values
L = 2 ##length of rod
N = 100 ##Number of point charges
Q = 3e-8
dQ = Q/N
dx = L/N
t = 0
x = (dx-L)/2
dVtotal = 0
Enet = vector(0,0,0)
##Calculations
while x < L/2:
sphere(pos=(x,0,0), radius =1/6, color=color.cyan)
x += dx
while marker.pos.y < 1.15:
x=(dx-L)/2
Enet=vector(0,0,0)
while x < L/2:
r=marker.pos - vector(x,0,0)
rmag=mag(r)
rhat=r/rmag
E=oofpez*dQ/rmag**2*rhat
Enet+=E
x+=dx
dV=-dot(Enet,.0005)
dVtotal=dVtotal+dV
t=t+dt
marker.pos=marker.pos+marker.v*dt
Vgraph.plot(pos=(t,dVtotal))
print ("dVtotal =", dVtotal, "volts")
Produces this error:
Traceback (most recent call last):
File "F:/Purdue/2nd semester/PHYS 272/Labs/lab5.py", line 49, in <module>
Vgraph.plot(pos=(t,dVtotal))
File "C:\Python32\lib\site-packages\vis\graph.py", line 742, in plot
pos,c = primitiveargs(self,args)
File "C:\Python32\lib\site-packages\vis\graph.py", line 708, in primitiveargs
pos = array(arguments['pos'], float)
ValueError: setting an array element with a sequence.
How do I fix it?
I'm working on a custom tiled map loader. Seems to work fine, I don't get any errors, but the screen only shows up 1 tile of each type.
this is the file structure:
/main.py
/other/render2.py
/other/render.py
here's the render2.py file:
import pyglet, json
from pyglet.window import key
from pyglet.gl import *
from ConfigParser import SafeConfigParser
from cocos.layer import *
from cocos.batch import *
from cocos.sprite import Sprite
class renderer( Layer ):
#init function
def __init__(self):
super( renderer, self ).__init__()
#call function, returns the map as a list of sprites, and coordinates
def __call__(self, mapname):
#runs the map file parser
parser = SafeConfigParser()
#reads the map file
try:
world = parser.read('maps/'+mapname+'.txt')
print world
except IOError:
return
#These variables the config from the map file
tileSize = int(parser.get('config', 'tilesize'))
layers = int(parser.get('config', 'layers'))
mapList = []
#the super mega advanced operation to render the mapList
for i in range(0,layers):
layer = json.loads(parser.get('layer'+str(i), 'map'))
tileType = parser.get('layer'+str(i), 'tiletype')
nTiles = int(parser.get('layer'+str(i), 'tiles'))
tileSet = []
#this over here loads all 16 tiles of one type into tileSet
for n in range(0, nTiles):
tileSet.append(Sprite("image/tiles/"+tileType+"/"+str(n)+".png", scale = 1, anchor = (0,0)))
for x in range(0, len(layer)):
for y in range(0, len(layer[x])):
X = (x*tileSize)
Y = (y*tileSize)
total = [tileSet[layer[x][y]], i, X, Y]
print layer[x][y], tileSet[layer[x][y]]
mapList.append(total)
return mapList
This is an example of what this returns :
[<cocos.sprite.Sprite object at 0x060910B0>, 0, 0,0 ]
[<cocos.sprite.Sprite object at 0x060910B0> , 0, 64,64 ]
It returns a huge list with a lot of sublists like these in it.
when I call it from the main.py file, it only draws the last tile of each kind.
here's the main.py file:
import sys, os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
import pyglet
import threading,time
from pyglet import clock
from pyglet.gl import *
from cocos.director import *
from cocos.menu import *
from cocos.scene import *
from cocos.layer import *
from cocos.actions import *
from cocos.batch import *
from cocos.sprite import Sprite
from other.render2 import renderer
import random; rr = random.randrange
class Background(ScrollableLayer):
def __init__(self):
super(Background, self).__init__()
world = renderer()
bg = world('sampleidea')
batch = BatchNode()
for i in range(0, len(bg)):
l= bg[i][1]
x= bg[i][2]
y= bg[i][3]
spr = bg[i][0]
spr.position =(x,y)
batch.add(spr, z = l)
self.add(batch)
class Menu(Layer):
def __init__(self):
super(Menu, self).__init__()
title = Sprite('image/title.png' )
title.position = (400,520)
self.add( title )
def start():
director.set_depth_test()
background = Background()
menu = Menu()
scene = Scene(background, menu)
return scene
def init():
director.init( do_not_scale=True, resizable=True, width=1280, height=720)
def run(scene):
director.run( scene )
if __name__ == "__main__":
init()
s = start()
run(s)
What am I doing wrong? I have an older render.py, which does work, but I remade it since it loaded each sprite file for each tile. That took way to long to load on big maps.
This is the old render.py I've been using before.
It's quite different since it used different map files too.
import pyglet, json
from pyglet.window import key
from pyglet.gl import *
from ConfigParser import SafeConfigParser
from cocos.layer import *
from cocos.batch import *
from cocos.sprite import Sprite
class renderer( Layer ):
def __init__(self):
super( renderer, self ).__init__()
def __call__(self, mapname):
parser = SafeConfigParser()
try:
world = parser.read('maps/'+mapname+'.txt')
print world
except IOError:
print("No world file!")
return
tilesize = json.loads(parser.get('data', 'tilesize'))
world = json.loads(parser.get('data', 'world'))
maplist = []
for l in range(len(world)):
for x in range(len(world[l])):
for y in range(len(world[l][x])):
if world[l][x][y] != None:
foldername = str(world[l][x][y][0])
imagename = str(world[l][x][y][1])
spr = Sprite("image/tiles/"+foldername+"/"+imagename+".png", scale = 1, anchor = (0,0))
X = (x*tilesize)
Y = (y*tilesize)
total = [spr, l, X, Y]
maplist.append(total)
return maplist
Is it possible to make the new "render" to work?
The problem is that my new optimized "renderer" creates a bunch of
cocos.sprite.Sprite objects, instead of just loading Image files as i thought it would. The code in my question only repositioned the same sprite object over and over again this way. To solve this, the way to do it is by opening the image with pyglet.image.load(), and creating sprite objects with that.
example:
f = pyglet.image.load('sprite.png')
batch = CocosNode()
batch.position = 50, 100
add(batch)
for i in range(0, 200):
test = Sprite(f)
test.position = i*10,i*10
batch.add( test )