In my application a user interacts with a 3D volumetric rendering. The data is quite noisy, but there are objects of interest buried in the noise. My users are able to get a good geometric sense of these objects by rotating and panning the scene.
Resolution is still crucial and I might be willing to trade it off for smoothness of interaction. Can I disable or at least modify this downsampling/lowering-of-resolution that accompanies scene interaction?
I've been asked to show my code.. I'll show some pieces.
class Display(HasTraits)
def __init__(self, list_of_MySourceObjects , list_of_corresponding_MyScenes )
...
def default_traits_view(self):
traits_view=View(HGroup( *list_ofMyScenes ) ##Allows variable number of scenes in view
...
class SomeSensibleCoordinateClass(HasTraits):
#Some logic for coordinate callbacks and manipulation
...
####Custom class that knows how to plot on scenes####
class MySourceObject(SomeSensibleCoordinateClass):
...
###I'll show a sample plotting function
def display_on_small_scene(self,scene):
self.origin=-self.radius.__array__()*self.spacing
print 'origin is',self.origin
self.small_array_src=ArraySource(scene,spacing=self.spacing,origin=self.origin)
self.scene=scene#for debug
self.set_scene_patch()### (re)sets self.array_src data
scene.mayavi_scene.add_child(self.array_src)
self.volume=self.array_src.add_module(self.vol_module)
scene.draw_axes(self.array_src.scalar_data.shape)
...
class MyScene(MlabSceneModel):
volume=Instance(Volume,())
some_other_custom_parameters = Any()
...
##Some default picking behavior
def picker_callback(self...):
...
##Some default aesthetics
def draw_axes(self,...):
Related
Download an OSM map from geofabrik.
Import it with osm2pgsql (basic commands, no fancy stuff)
You will have your tables ready to use.
Here's are my models (all the same fields for Line, Polygon, Point and Roads, just one is enough):
class PlanetOsmLine(models.Model):
class Meta:
db_table = 'planet_osm_line'
managed = False
osm_id = models.BigIntegerField(primary_key=True)
# ...tons of other field (unused)...
way = GeometryField(default=None)
Now, to display it in the admin interface, basic admin.ModelAdmin does the job and it work, like this for a road:
Let's add the OSMGeoAdmin interface with this code:
class PlanetOsmAdmin(OSMGeoAdmin):
pass
my_admin_site.register(PlanetOsmLine, PlanetOsmAdmin)
my_admin_site.register(PlanetOsmPolygon, PlanetOsmAdmin)
my_admin_site.register(PlanetOsmPoint, PlanetOsmAdmin)
my_admin_site.register(PlanetOsmRoads, PlanetOsmAdmin)
You'll get this, which is way nicer:
OSM Admin works with everything except polygons. Here's the basic view:
And when I do my_admin_site.register(PlanetOsmPolygon, PlanetOsmAdmin) then I get only this, always the same place:
If the polygons are displayed properly without OSMGeoAdmin, and are not displayed properly with it. There's no error in the console log of Chrome.
What am I missing?
Ok I found the problem. You can override some values in OSMGeoAdmin, and setting display_wkt to True showed me it was empty.
class PlanetOsmAdmin(OSMGeoAdmin):
display_wkt = True
So I did a step-by-step debugging and found out that my value for polygons are:
SRID=3857;POLYGON ((5024019.9 -1441890.9, ..., 5024019.9 -1441890.690534543))
In the source code (/Lib/site-packages/django/contrib/gis/admin/widgets.py) they ignore the value if it's not of the same expected type (or if it's not GEOMETRY):
So I've commented those 3 lines and now it works.
The working solution I've implemented is:
if (value and value.geom_type.upper() != self.geom_type and
self.geom_type != 'GEOMETRY' and
(self.geom_type == 'MULTIPOLYGON' and
'POLYGON' not in value.geom_type.upper())):
value = None
While playing around with different ways to show a webcam feed (obtained using imageio/ffmpeg) in a PyQt4 window, I stumbled upon this answer. After implementing this in Python 2.7 as an ImageDisplayWidget class (as summarized below), everything seems to work just fine: A window opens, showing my webcam feed without a glitch. If I close the window, everything is stopped and closed neatly.
But... Whenever I click anywhere outside this PyQt window (while it is showing the webcam feed), causing it to lose focus, Python.exe crashes with an unhandled win32 exception. The same happens when I try to resize the window.
I am probably making some kind of exceedingly silly beginner's mistake, but I just don't see it. Can anyone point me in the right direction? Am I breaking some basic rule of (Py)Qt or even Python?
Here's a minimal example:
import sys
import numpy
from PIL import Image, ImageQt # pillow
from PyQt4 import QtGui, QtCore
class DummyVideoGrabber(QtCore.QTimer):
signal_image_available = QtCore.pyqtSignal(QtGui.QImage)
def __init__(self):
super(DummyVideoGrabber, self).__init__()
self.timeout.connect(self.update_image)
self.counter = 0
def update_image(self):
# Dummy rgb image (in reality we get a numpy array from imageio's Reader)
self.counter += 1
numpy_image = numpy.zeros(shape=(480, 640, 3), dtype=numpy.int8)
numpy_image[:, :, self.counter%3] = 255
qt_image = ImageQt.ImageQt(Image.fromarray(numpy_image, mode='RGB'))
# Emit image
self.signal_image_available.emit(qt_image)
class ImageDisplayWidget(QtGui.QWidget):
"""
Custom widget that displays an image using QPainter.
Mostly copied from: https://stackoverflow.com/a/22355028/4720018
"""
def __init__(self, size_wxh=None, parent=None):
super(ImageDisplayWidget, self).__init__(parent)
self.image = QtGui.QImage()
def set_image(self, qimage, resize_window=False):
self.image = qimage
self.repaint()
def paintEvent(self, QPaintEvent):
if not self.image:
return
painter = QtGui.QPainter(self)
painter.drawImage(self.rect(), self.image, self.image.rect())
app = QtGui.QApplication(sys.argv)
# instantiate a display object
display = ImageDisplayWidget()
display.resize(640, 480)
display.show()
# instantiate a grabber object
grabber = DummyVideoGrabber()
grabber.signal_image_available.connect(display.set_image)
grabber.start(100) # timer interval in ms
# start the event loop
app.exec_()
I found that the crash can be prevented by adding a wasActiveWindow flag (initialized to True in the constructor) and encapsulating the drawImage() call in some logic like so:
if self.isActiveWindow():
if self.wasActiveWindow:
painter.drawImage(self.rect(), self.image, self.image.rect())
self.wasActiveWindow = True
else:
self.wasActiveWindow = False
However, resizing the window still crashes python.
Problem solved by keeping a reference to the qt_image as self.qt_image:
...
# Emit image
self.qt_image = ImageQt.ImageQt(Image.fromarray(numpy_image, mode='RGB'))
self.signal_image_available.emit(self.qt_image)
...
This way it works as it should. Don't need the self.wasActiveWindow workaround anymore.
Still not sure why not keeping a reference would lead to a low-level python crash though...
I want to detect people without relying on face detection. In cases where lighting conditions are poor, or Pepper is facing away, people are not detected.
The memory events 'PeoplePerception/JustArrived' and 'EngagementZones/PersonApproached' seem to rely on faces being detectable by the camera.
Is there a memory event which is triggered by changes in laser/infrared/sonar distance?
I wonder if there is a better solution than:
while True:
floatDist = self.memory.getData('Device/SubDeviceList/Platform/Front/Sonar/Sensor/Value')
if floatDist < 1.0:
doSomething()
sleep(0.5)
You can use the front sonar and the event "FaceDetected" for the human detection.
But you can use a PeriodicTask and not a while loop. You while check the event each 0.5secs and you will be allowed to stop it.
I will do it like that :
class HumanDetector:
def __init__(self, ALMemory):
self.ALMemory = ALMemory
# subscribe to FaceDetected
self.subscriber = self.ALMemory.subscriber("FaceDetected")
self.subscriber.signal.connect(self.on_human_tracked)
self.task = qi.PeriodicTask()
self.task.setCallback(self._task)
self.task.setUsPeriod(50000)
self.task.start(True)
def on_human_tracked(self, value):
print "do something with the face"
def _stop(self):
print "_stop..."
self.task.stop()
self.face_detection.unsubscribe("FaceDetected")
print "_stop done"
def _task(self):
print "_task..."
floatDist = self.memory.getData('Device/SubDeviceList/Platform/Front/Sonar/Sensor/Value')
if floatDist < 1.0:
print "do something with the object in front of the robot"
print "_task done"
So it is an example of a python Class that need the module ALMemory.
With the module ALMemory you will check the sonar and if a face is detected.
I'm new to Kivy so still learning how to make content with the library. My question is related to the widgets and layouts. I'm trying to create some kind of 3D visualizer with OpenGL and just started looking at the built-in examples 3DRendering you can check it here.
I've changed the Original Example and in the class Renderer(Widget) i've added a method for reposition the widget itself:
def reposition_b1(self, *args):
self.pos = self.x, self.height / 2 - self.height / 2
and in the RendererApp Class within the build method:
def build(self):
b = BoxLayout(orientation='horizontal')
r1= Renderer()
r1.reposition_b1(500)
r2= Renderer()
b.add_widget(r1)
b.add_widget(r2)
return b
So from what I understand about Kivy it should give the next result (The magenta color in the background is just a reference):expected result
But instead I just got a single 3D model in the visualizer. Any Hints about what I'm missing?
I have a coordinate system that it makes sense to treat as a "whole group". They initialize, change, and reset simultaneously. I also like to not re-render as many times as I have coordinates when one changes. Here is the simplified version of what I have in mind, but I can't quite get there. Thanks.
Cleaner code is better in my case even if it uses more advanced features. Could the class 'Coord' be wrapped as a trait itself?
from traits.api import *
class Coord(HasTraits):
x=Float(1.0)
y=Float(1.0)
def __init__(self,**traits):
HasTraits.__init__(self,**traits)
class Model:
coord=Instance(Coord)
#on_trait_change('coord')##I would so have liked this to "just work"
def render(self):#reupdate render whenever coordinates change
class Visualization:
model=Instance(Model)
def increment_x(self):
self.model.coord.x+=1 ##should play well with Model.render
def new_coord(self):
self.model.coord=Coord(x=2,y=2) ##should play well with Model.render
There are a couple of issues with your source code. Model and Visualization both need to be HasTraits classes for the listener to work.
Also, it is rare to actually need to write the __init__ method of a HasTraits class. Traits is designed to work without it. That said, if you do write an __init__ method, make sure to use super to properly traverse the method resolution order. (Note that you will find this inconsistently implemented in the extant documentation and examples.)
Finally, use the 'anytrait' name to listen for any trait:
from traits.api import Float, HasTraits, Instance, on_trait_change
class Coord(HasTraits):
x=Float(1.0)
y=Float(1.0)
class Model(HasTraits):
coord=Instance(Coord, ())
#on_trait_change('coord.anytrait') # listens for any trait on `coord`.
def render(self):
print "I updated"
class Visualization(HasTraits):
model=Instance(Model, ())
def increment_x(self):
self.model.coord.x+=1 # plays well with Model.render
def new_coord(self):
self.model.coord=Coord(x=2,y=2) # plays well with Model.render
Here's my output:
>>> v = Visualization()
>>> v.increment_x()
I updated
>>> v.new_coord()
I updated