public Pair<List<Rectangle>, HeatMap> detect(BufferedImage image) { Timer timer = new Timer(); timer.start(); setCaffeMode(caffe_gpu); PreprocessedImage processedImage = processImage(image, NETWORK_INPUT_WIDTH, NETWORK_INPUT_HEIGHT); FloatPointer pointer = new FloatPointer(processedImage.data.length); pointer.put(processedImage.data); float[] output; synchronized (caffeNetLock) { caffe_net.input_blobs().get(0).set_cpu_data(pointer); output = transferNetworkOutputToJava(caffe_net.Forward()); } HeatMap outputMap = new HeatMap(0, 0, NETWORK_OUTPUT_WIDTH, NETWORK_OUTPUT_HEIGHT); System.arraycopy(output, 0, outputMap.data, 0, output.length); final float outputScaleX = outputMap.w / (float)NETWORK_INPUT_WIDTH; final float outputScaleY = outputMap.h / (float)NETWORK_INPUT_HEIGHT; List<Component> components = findComponents(binarize(outputMap)); List<Rectangle> result = new ArrayList<>(); for (Component component : components) { float inputScaleX = NETWORK_INPUT_WIDTH / (float) image.getWidth(); float inputScaleY = NETWORK_INPUT_HEIGHT / (float) image.getHeight(); result.add(componentBound(component, inputScaleX, inputScaleY, outputScaleX, outputScaleY)); } System.out.println("Total detection time: " + timer.lap()); return Pair.of(result, outputMap); }
NETWORK_OUTPUT_WIDTH = caffe_net.output_blobs().get(0).shape(3); NETWORK_OUTPUT_HEIGHT = caffe_net.output_blobs().get(0).shape(2); NETWORK_INPUT_WIDTH = caffe_net.input_blobs().get(0).shape(3); NETWORK_INPUT_HEIGHT = caffe_net.input_blobs().get(0).shape(2);
public CaffeClassifier(FloatNet net, Mat mean, List<String> labels) { this.net = net; this.mean = mean; this.labels = labels; this.inputLayer = net.input_blobs().get(0); this.numChannels = inputLayer.channels(); this.width = inputLayer.width(); this.height = inputLayer.height(); this.inputGeometry = new Size(width, height); if (numChannels != 1 && numChannels != 3) { throw new IllegalStateException("Input layer should have 1 or 3 channels"); } }
private static Mat meanImage(String meanFile, FloatNet net) { BlobProto blobProto = new BlobProto(); ReadProtoFromBinaryFileOrDie(meanFile, blobProto); FloatBlob meanBlob = new FloatBlob(); meanBlob.FromProto(blobProto); int numChannels = meanBlob.channels(); FloatBlob inputLayer = net.input_blobs().get(0); if (numChannels != inputLayer.channels()) { throw new IllegalStateException("Number of channels of mean file doesn't match input layer"); } Mat[] channels = new Mat[numChannels]; FloatPointer data = meanBlob.mutable_cpu_data(); int meanHeight = meanBlob.height(); int meanWidth = meanBlob.width(); for (int i = 0; i < numChannels; i++) { data.position(i * meanHeight * meanWidth * data.sizeof()); channels[i] = new Mat(meanHeight, meanWidth, CV_32FC1, data); } Mat mean = new Mat(); merge(new MatVector(channels), mean); Scalar channelMean = mean(mean); return new Mat(inputLayer.height(), inputLayer.width(), mean.type(), channelMean); }
private MatVector wrapInputLayer() { Mat[] inputChannels = new Mat[numChannels]; FloatPointer inputData = net.input_blobs().get(0).mutable_cpu_data(); for (int i = 0; i < numChannels; i++) { inputData.position(i * width * height * inputData.sizeof()); inputChannels[i] = new Mat(height, width, CV_32FC1, inputData); } return new MatVector(inputChannels); }