Skip to content

Instantly share code, notes, and snippets.

@wtnb75
Last active December 11, 2017 15:37
Show Gist options
  • Save wtnb75/80f5a2f1892f9ee349d55b0d865a023e to your computer and use it in GitHub Desktop.
Save wtnb75/80f5a2f1892f9ee349d55b0d865a023e to your computer and use it in GitHub Desktop.
cpu-caffe vs. movidius ncs
from mvnc import mvncapi as mvnc
import cv2
import numpy
import os
import time
import subprocess
import caffe
import click
import struct
class RunByCaffe:
def __init__(self, labelfn, meanfn, prototxt, caffemodel):
self.dim = (227, 227)
self.labels = numpy.loadtxt(labelfn, str, delimiter="\t")
self.mean = numpy.load(meanfn).mean(1).mean(1)
self.net = caffe.Net(prototxt, caffemodel, caffe.TEST)
self.transformer = caffe.io.Transformer(
{'data': self.net.blobs['data'].data.shape})
self.transformer.set_transpose('data', (2, 0, 1))
self.transformer.set_mean('data', self.mean)
self.transformer.set_raw_scale('data', 255)
self.transformer.set_channel_swap('data', (2, 1, 0))
caffe.set_mode_cpu()
def loadimg(self, fn):
# print("loading", fn)
image = caffe.io.load_image(fn)
transformed_image = self.transformer.preprocess('data', image)
return transformed_image
def classify(self, img):
# self.net.blobs['data'].reshape(1, 3, self.dim[0], self.dim[1])
self.net.blobs['data'].data[...] = [img]
output = self.net.forward()
output_prob = output['prob'][0]
return output_prob
class RunByMovidius(RunByCaffe):
def __init__(self, labelfn, meanfn, graph):
self.dim = [227, 227]
self.channel = 3
with open(graph, "rb") as ifp:
ifp.seek(0xfa)
cpus, = struct.unpack("h", ifp.read(2))
print("cpus", cpus + 1)
ifp.seek(0x178)
width, height, channel = struct.unpack("3i", ifp.read(4 * 3))
self.dim[0] = width
self.dim[1] = height
self.channels = channel
print("width", width, "height", height, "channel", channel)
self.labels = numpy.loadtxt(labelfn, str, delimiter="\t")
self.mean = numpy.load(meanfn).mean(1).mean(1)
if False:
self.transformer = caffe.io.Transformer(
{'data': (1, self.channel, self.dim[0], self.dim[1])})
self.transformer.set_transpose('data', (2, 0, 1))
self.transformer.set_mean('data', self.mean)
self.transformer.set_raw_scale('data', 255)
self.transformer.set_channel_swap('data', (2, 1, 0))
mvnc.SetGlobalOption(mvnc.GlobalOption.LOG_LEVEL, 2)
devices = mvnc.EnumerateDevices()
if len(devices) == 0:
print('No devices found')
quit()
self.device = mvnc.Device(devices[0])
self.device.OpenDevice()
with open(graph, mode='rb') as f:
blob = f.read()
self.graph = self.device.AllocateGraph(blob)
def loadimg(self, fn):
# print("loading", fn)
img = cv2.imread(fn)
img = cv2.resize(img, tuple(self.dim))
img = img.astype(numpy.float16)
img[:, :, 0] = (img[:, :, 0] - self.mean[0])
img[:, :, 1] = (img[:, :, 1] - self.mean[1])
img[:, :, 2] = (img[:, :, 2] - self.mean[2])
return img
def classify(self, img):
self.graph.LoadTensor(img.astype(numpy.float16), 'user object')
output, userobj = self.graph.GetResult()
return output
def __del__(self):
if hasattr(self, "graph"):
self.graph.DeallocateGraph()
if hasattr(self, "device"):
self.device.CloseDevice()
class RunByMovidius2(RunByMovidius):
def __init__(self, labelfn, meanfn, prototxt, caffemodel):
if not os.path.exists("graph"):
res = subprocess.run(["mvNCCompile", "-w", caffemodel, "-s", "12", prototxt])
print("result", res)
RunByMovidius.__init__(self, labelfn, meanfn, "graph")
def getts(ts):
return list(map(lambda f: f[1] - f[0], zip(ts, ts[1:])))
@click.group(invoke_without_command=True)
@click.pass_context
def cli(ctx):
if ctx.invoked_subcommand is None:
print(ctx.get_help())
else:
print('gonna invoke %s' % ctx.invoked_subcommand)
def do_solve(solver, images):
print("images", images)
print("|file|time(load)|time(eval)|id|prob|label|")
print("|----|---------:|---------:|--|----|-----|")
for i in images:
ts = [time.time()]
img = solver.loadimg(i)
ts.append(time.time())
output = solver.classify(img)
ts.append(time.time())
loadtime, evaltime = getts(ts)
am = output.argmax()
print("|%s|%.3f|%.3f|%s|%.2f|%s|" % (os.path.basename(i),
loadtime, evaltime, am, output[am], solver.labels[am]))
@cli.command()
@click.option("--label")
@click.option("--mean")
@click.option("--prototxt")
@click.option("--caffemodel")
@click.argument("images", nargs=-1)
def bycaffe(label, mean, prototxt, caffemodel, images):
solver = RunByCaffe(label, mean, prototxt, caffemodel)
do_solve(solver, images)
@cli.command()
@click.option("--label")
@click.option("--mean")
@click.option("--graph")
@click.argument("images", nargs=-1)
def byncs(label, mean, graph, images):
solver = RunByMovidius(label, mean, graph)
do_solve(solver, images)
@cli.command()
@click.option("--label")
@click.option("--mean")
@click.option("--prototxt")
@click.option("--caffemodel")
@click.argument("images", nargs=-1)
def byncs2(label, mean, prototxt, caffemodel, images):
solver = RunByMovidius2(label, mean, prototxt, caffemodel)
do_solve(solver, images)
def main():
cli()
if __name__ == "__main__":
main()
@wtnb75
Copy link
Author

wtnb75 commented Nov 6, 2017

rev2: fix loading image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment