package developer.depth; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.channels.FileChannel; import java.util.Map; import developer.Ros; import developer.image.ImageUtils; import oculusPrime.Application; import oculusPrime.PlayerCommands; import oculusPrime.Util; public class OpenNIRead { private boolean depthCamInit = false; public boolean depthCamGenerating = false; private static ByteBuffer frameData; private int[] lastresult; Process camproc; File lockfile = new File("/run/shm/xtion.raw.lock"); ImageUtils imageUtils = new ImageUtils(); private static int width = 320; private static int height = 240; private final static int BYTEDEPTH = 2; public boolean startDepthCam() { if (depthCamInit) return false; oculusPrime.Util.log("START ros openni 320x240", this); lockfile.delete(); // new Thread(new Runnable() { // public void run() { // try { // // String sep = System.getProperty("file.separator"); // String dir = System.getenv("RED5_HOME")+sep+"xtionread"; // String javadir = System.getProperty("java.home"); // String cmd = javadir+sep+"bin"+sep+"java"; // String arg = dir+sep+"xtion.jar"; // ProcessBuilder pb = new ProcessBuilder(cmd, "-jar", arg); // Map<String, String> env = pb.environment(); // env.put("LD_LIBRARY_PATH", dir); // camproc = pb.start(); // // } catch (Exception e) { // e.printStackTrace(); // } // } // }).start(); // String cmd = Application.RED5_HOME+Util.sep+"ros.sh"; // setup ros environment // cmd += " roslaunch oculusprime depthcam_to_java.launch"; // Util.systemCall(cmd); if (!Ros.launch("depthcam_to_java")) return false; depthCamGenerating = true; depthCamInit = true; return true; } public void stopDepthCam() { if (!depthCamInit) return; oculusPrime.Util.log("STOP ros openni 320x240", this); Util.systemCall("pkill roslaunch"); depthCamInit = false; depthCamGenerating = false; } public int[] readHorizDepth(int y) { int[]result = new int[width]; int size = width*height*BYTEDEPTH; getFrame(size); boolean blank=true; // for (int x=0; x<width; x++) { int i = 0; for (int x=width-1; x>=0; x--) { int p = ((width * y)+x)*BYTEDEPTH; // float depth = frameData.getFloat(p); // reads 4 bytes // result[i] = (short) (depth*1000); short depth = frameData.getShort(p); // reads 2 bytes result[i] = depth; i++; if (depth != 0) { blank = false; } } if (blank) { return lastresult; } else { lastresult = result; return result; } } public short[] readFullFrame() { short[] result = new short[width*height]; int size = width*height*BYTEDEPTH; boolean blank=true; while (true) { boolean rcpt = getFrame(size); int i = 0; for (int y=0; y<height; y++) { for (int x=width-1; x>=0; x--) { int p = ((width * y)+x)*BYTEDEPTH; // float depth = frameData.getFloat(p); // reads 4 bytes // result[i] = (short) (depth*1000); // convert to mm short depth = frameData.getShort(p); // reads 2 bytes result[i] = depth; i++; if (depth != 0) { blank = false; } } } if (!blank && rcpt) break; else { if (blank) Util.debug("depth frame blank", this); if (!rcpt) Util.debug("depth frame not rcvd", this); } } return result; } private boolean getFrame(int size) { long start = System.currentTimeMillis(); while (true) { if (!lockfile.exists()) { break; } long now = System.currentTimeMillis(); if (now - start > 5000) { Util.debug("lockfile timeout", this); return false; // 5 sec timeout } } try { lockfile.createNewFile(); FileInputStream file = new FileInputStream("/run/shm/xtion.raw"); FileChannel ch = file.getChannel(); if (ch.size() == size) { frameData = ByteBuffer.allocate((int) size); ch.read(frameData.order(ByteOrder.LITTLE_ENDIAN)); ch.close(); file.close(); lockfile.delete(); return true; } else Util.debug("frame size not matching", this); ch.close(); file.close(); } catch (Exception e) { e.printStackTrace(); } return false; } public BufferedImage generateDepthFrameImg() { short[] depth = readFullFrame(); final int maxDepthInMM = 5000; // 3500 BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // Graphics2D g2d = img.createGraphics(); for(int y=0; y<height; y++) { // for (int x=width-1; x>=0; x--) { for(int x=0; x<width; x++) { int hue = depth[x + y*width]; if (hue > maxDepthInMM) hue = maxDepthInMM; if (hue != 0) { hue = 255 - (int) ((float) (hue)/maxDepthInMM * 255f); } int argb = (hue<<16) + (0<<8) + hue; // short d = depth[x + y*width]; // if (d > maxDepthInMM) d = 0; // int red = d >> 8; // red *=8; // int blue=0; // if (d != 0) blue = 255 - (int) ((float) (d)/maxDepthInMM * 255f); // int argb = (red<<16) + (0<<8) + blue; img.setRGB(width-x-1, y, argb); // flip horiz } } // int[] greypxls = imageUtils.convertToGrey(img); // int[] edgepxls = imageUtils.edges(greypxls, img.getWidth(), img.getHeight()); // BufferedImage edgeimg = imageUtils.intToImage(edgepxls, img.getWidth(), img.getHeight()); // // return edgeimg; return img; } public static void main(String s[]) { OpenNIRead read = new OpenNIRead(); read.startDepthCam(); int size = width*height*BYTEDEPTH; read.getFrame(size); System.out.println(frameData.capacity()); } }