1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // Extract histogram from image. 18 19 package androidx.media.filterpacks.histogram; 20 21 import androidx.media.filterfw.Filter; 22 import androidx.media.filterfw.Frame; 23 import androidx.media.filterfw.FrameBuffer2D; 24 import androidx.media.filterfw.FrameType; 25 import androidx.media.filterfw.InputPort; 26 import androidx.media.filterfw.MffContext; 27 import androidx.media.filterfw.OutputPort; 28 import androidx.media.filterfw.Signature; 29 30 import java.nio.ByteBuffer; 31 import java.nio.ByteOrder; 32 import java.nio.FloatBuffer; 33 34 /** 35 * ChromaHistogramFilter takes in an image in HSVA format and computes a 2-D histogram with a 36 * 2 dimensional chroma histogram based on hue (column) and saturation (row) at the top and 37 * a 1-D value histogram in the last row. The number of bin in the value histogram equals to 38 * the number of bins in hue. 39 */ 40 public final class NewChromaHistogramFilter extends Filter { 41 42 private int mHueBins = 6; 43 private int mSaturationBins = 3; 44 private int mValueBins; 45 46 private int mSaturationThreshold = 26; // 255 * 0.1 47 private int mValueThreshold = 51; // 255 * 0.2 48 49 public NewChromaHistogramFilter(MffContext context, String name) { 50 super(context, name); 51 } 52 53 @Override 54 public Signature getSignature() { 55 FrameType imageIn = FrameType.image2D(FrameType.ELEMENT_RGBA8888, FrameType.READ_CPU); 56 FrameType dataOut = FrameType.buffer2D(FrameType.ELEMENT_FLOAT32); 57 58 return new Signature() 59 .addInputPort("image", Signature.PORT_REQUIRED, imageIn) 60 .addInputPort("huebins", Signature.PORT_OPTIONAL, FrameType.single(int.class)) 61 .addInputPort("saturationbins", Signature.PORT_OPTIONAL, FrameType.single(int.class)) 62 .addInputPort("saturationthreshold", Signature.PORT_OPTIONAL, 63 FrameType.single(int.class)) 64 .addInputPort("valuethreshold", Signature.PORT_OPTIONAL, FrameType.single(int.class)) 65 .addOutputPort("histogram", Signature.PORT_REQUIRED, dataOut) 66 .disallowOtherPorts(); 67 } 68 69 @Override 70 public void onInputPortOpen(InputPort port) { 71 if (port.getName().equals("huebins")) { 72 port.bindToFieldNamed("mHueBins"); 73 port.setAutoPullEnabled(true); 74 } else if (port.getName().equals("saturationbins")) { 75 port.bindToFieldNamed("mSaturationBins"); 76 port.setAutoPullEnabled(true); 77 } else if (port.getName().equals("saturationthreshold")) { 78 port.bindToFieldNamed("mSaturationThreshold"); 79 port.setAutoPullEnabled(true); 80 } else if (port.getName().equals("valuethreshold")) { 81 port.bindToFieldNamed("mValueThreshold"); 82 port.setAutoPullEnabled(true); 83 } 84 } 85 86 @Override 87 protected void onProcess() { 88 FrameBuffer2D imageFrame = getConnectedInputPort("image").pullFrame().asFrameImage2D(); 89 OutputPort outPort = getConnectedOutputPort("histogram"); 90 91 mValueBins = mHueBins; 92 int[] outDims = new int[] {mHueBins, mSaturationBins + 1}; 93 FrameBuffer2D histogramFrame = outPort.fetchAvailableFrame(outDims).asFrameBuffer2D(); 94 95 ByteBuffer imageBuffer = imageFrame.lockBytes(Frame.MODE_READ); 96 ByteBuffer histogramBuffer = histogramFrame.lockBytes(Frame.MODE_READ); 97 histogramBuffer.order(ByteOrder.nativeOrder()); 98 FloatBuffer floatHistogram = histogramBuffer.asFloatBuffer(); 99 100 // Run native method 101 extractChromaHistogram(imageBuffer, floatHistogram, mHueBins, mSaturationBins, mValueBins, 102 mSaturationThreshold, mValueThreshold); 103 104 imageFrame.unlock(); 105 histogramFrame.unlock(); 106 107 outPort.pushFrame(histogramFrame); 108 } 109 110 private static native void extractChromaHistogram(ByteBuffer imageBuffer, 111 FloatBuffer histogramBuffer, int hueBins, int saturationBins, int valueBins, 112 int saturationThreshold, int valueThreshold); 113 114 static { 115 System.loadLibrary("smartcamera_jni"); 116 } 117 } 118