Home | History | Annotate | Download | only in filterfw
      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