# HG changeset patch # User Drew Perttula # Date 2017-05-30 08:37:25 # Node ID 17da56a3c8df68acf9f70990f471a123fedffe6d # Parent 2239d5648932db97a7d6253092dbb7bf4ad25f0a group device captures into sessions, limit solver to specific ones Ignore-this: b91d858ebb435973b9742bed00567ffd diff --git a/bin/captureDevice b/bin/captureDevice --- a/bin/captureDevice +++ b/bin/captureDevice @@ -15,25 +15,25 @@ from greplin import scales from run_local import log from lib.cycloneerr import PrettyErrorHandler -from light9.namespaces import L9 +from light9.namespaces import L9, RDF from light9 import networking, showconfig from light9.rdfdb.syncedgraph import SyncedGraph from light9.paint.capture import writeCaptureDescription from light9.greplin_cyclone import StatsForCyclone from light9.effect.settings import DeviceSettings from light9.effect.sequencer import sendToCollector +from light9.rdfdb.patch import Patch stats = scales.collection('/webServer', scales.PmfStat('setAttr')) - class Camera(object): def __init__(self, imageUrl): self.imageUrl = imageUrl def takePic(self, uri, writePath): log.info('takePic %s', uri) - return treq.get(self.imageUrl).addCallbacks(lambda r: self._done(writePath, r), - log.error) + return treq.get(self.imageUrl).addCallbacks( + lambda r: self._done(writePath, r), log.error) @inlineCallbacks def _done(self, writePath, response): @@ -56,6 +56,7 @@ class Capture(object): settleTime = .5 def __init__(self, graph, dev): self.graph = graph + self.dev = dev def steps(a, b, n): return [round(a + (b - a) * i / n, 5) for i in range(n)] @@ -77,6 +78,15 @@ class Capture(object): (dev, L9['color'], '#ffffff'), ])) + self.devTail = dev.rsplit('/')[-1] + self.session = URIRef('/'.join([showconfig.showUri(), + 'capture', self.devTail, self.captureId])) + self.ctx = URIRef(self.session + '/index') + + self.graph.patch(Patch(addQuads=[ + (self.session, RDF.type, L9['CaptureSession'], self.ctx), + ])) + self.numPics = 0 self.settingsCache = set() self.step().addErrback(log.error) @@ -101,20 +111,17 @@ class Capture(object): yield deferSleep(self.firstMoveTime if self.numPics == 0 else self.settleTime) - dev = settings.devices()[0] - devTail = dev.rsplit('/')[-1] picId = 'pic%s' % self.numPics - path = '/'.join(['capture', devTail, self.captureId, picId]) + '.jpg' - ctx = URIRef('/'.join([showconfig.showUri(), - 'capture', devTail, self.captureId, 'index'])) - uri = URIRef('/'.join([showconfig.showUri(), - 'capture', devTail, self.captureId, picId])) + path = '/'.join([ + 'capture', self.devTail, self.captureId, picId]) + '.jpg' + uri = URIRef(self.session + '/' + picId) yield camera.takePic(uri, os.path.join(showconfig.root(), path)) self.numPics += 1 - writeCaptureDescription(self.graph, ctx, uri, dev, path, - self.settingsCache, settings) + writeCaptureDescription(self.graph, self.ctx, self.session, uri, + self.dev, + path, self.settingsCache, settings) reactor.callLater(0, self.step) diff --git a/bin/paintserver b/bin/paintserver --- a/bin/paintserver +++ b/bin/paintserver @@ -53,7 +53,7 @@ class App(object): def launch(self, *args): - self.solver = light9.paint.solve.Solver(self.graph) + self.solver = light9.paint.solve.Solver(self.graph, sessions=[L9['show/dance2017/capture/moving1/cap961804']]) self.solver.loadSamples() self.cycloneApp = cyclone.web.Application(handlers=[ diff --git a/light9/paint/capture.py b/light9/paint/capture.py --- a/light9/paint/capture.py +++ b/light9/paint/capture.py @@ -5,8 +5,8 @@ from light9.rdfdb.patch import Patch from light9.namespaces import L9, RDF from light9.paint.solve import loadNumpy -def writeCaptureDescription(graph, ctx, uri, dev, outPath, settingsSubgraphCache, - settings): +def writeCaptureDescription(graph, ctx, session, uri, dev, outPath, + settingsSubgraphCache, settings): graph.patch(Patch(addQuads=settings.statements( uri, ctx=ctx, settingRoot=URIRef('/'.join([ @@ -14,6 +14,7 @@ def writeCaptureDescription(graph, ctx, settingsSubgraphCache=settingsSubgraphCache))) graph.patch(Patch(addQuads=[ (dev, L9['capture'], uri, ctx), + (session, L9['capture'], uri, ctx), (uri, RDF.type, L9['LightSample'], ctx), (uri, L9['imagePath'], URIRef('/'.join([ showconfig.showUri(), outPath])), ctx), diff --git a/light9/paint/solve.py b/light9/paint/solve.py --- a/light9/paint/solve.py +++ b/light9/paint/solve.py @@ -67,8 +67,9 @@ class ImageDistAbs(object): class Solver(object): - def __init__(self, graph, imgSize=(100, 75)): + def __init__(self, graph, sessions=None, imgSize=(100, 75)): self.graph = graph + self.sessions = sessions self.imgSize = imgSize self.samples = {} # uri: Image array (float 0-255) self.fromPath = {} # imagePath: image array @@ -79,15 +80,19 @@ class Solver(object): """learn what lights do from images""" with self.graph.currentState() as g: - for samp in g.subjects(RDF.type, L9['LightSample']): - pathUri = g.value(samp, L9['imagePath']) - self.samples[samp] = self.fromPath[pathUri] = loadNumpy(pathUri.replace(L9[''], '')).astype(float) - self.blurredSamples[samp] = self._blur(self.samples[samp]) - - key = (samp, pathUri) - self.sampleSettings[key] = DeviceSettings.fromResource(self.graph, samp) + for sess in self.sessions: + for cap in g.objects(sess, L9['capture']): + self._loadSample(g, cap) log.info('loaded %s samples', len(self.samples)) - + + def _loadSample(self, g, samp): + pathUri = g.value(samp, L9['imagePath']) + self.samples[samp] = self.fromPath[pathUri] = loadNumpy(pathUri.replace(L9[''], '')).astype(float) + self.blurredSamples[samp] = self._blur(self.samples[samp]) + + key = (samp, pathUri) + self.sampleSettings[key] = DeviceSettings.fromResource(self.graph, samp) + def _blur(self, img): return scipy.ndimage.gaussian_filter(img, 10, 0, mode='nearest')