/*
 * Copyright 2016 Jan Dorazil <deu439@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "detectltp.hpp"
#include "lbph.hpp"
#include "slidinghistogram.hpp"

#include <opencv2/opencv.hpp>

using namespace cv;

DetectLTP::DetectLTP(int size, float thresh, int N, int R, float alpha)
  : mSize(size), mThresh(thresh), mN(N), mR(R), mAlpha(alpha)
{
}

void DetectLTP::process(DataUnit& data)
{
  assert(!data.mMat[TEMP].empty());
  assert(!data.mMat[TROI].empty());
  assert(!data.mMat[INPU].empty());
  
  // Calculate local binary patterns on the images
  Mat tempLBP, inpuLBP;
//   lbph::mb_lbp(data.mMat[TEMP], tempLBP);
//   lbph::mb_lbp(data.mMat[INPU], inpuLBP);
//   lbph::elbp(data.mMat[TEMP], tempLBP, 3, 8);
//   lbph::elbp(data.mMat[INPU], inpuLBP, 3, 8);
  lbph::eltp(data.mMat[TEMP], tempLBP, mR, mN, mAlpha);
  lbph::eltp(data.mMat[INPU], inpuLBP, mR, mN, mAlpha);
  lbph::remap(tempLBP);
  lbph::remap(inpuLBP);
  
  // Construct histograms over the patterns and compare it
  std::vector<SlidingHistogram::binType> int1, int2;
  SlidingHistogram hist(tempLBP.size(), tempLBP.channels(), NBINS, NBINS-1);
  hist.integralHistogram(tempLBP, int1);
  hist.integralHistogram(inpuLBP, int2);
  hist.compare(int1, int2, Size(mSize, mSize), data.mMat[OUTP]);
  
  // Threshold the result  
  data.mMat[OUTP] = data.mMat[OUTP] > mThresh;
  
  // Add padding back to original size
  int margin = mR + mSize / 2;
  copyMakeBorder(data.mMat[OUTP], data.mMat[OUTP], margin, margin,
                 margin, margin, BORDER_CONSTANT, Scalar(0));
  
  // Keep changes in ROI only
  multiply(data.mMat[OUTP], data.mMat[TROI], data.mMat[OUTP]);
  
//   normalize(data.mMat[OUTP], data.mMat[OUTP], 0, 255, NORM_MINMAX, CV_8U);
//   normalize(tempLBP, tempLBP, 0, 255, NORM_MINMAX, CV_8U);
//   normalize(inpuLBP, inpuLBP, 0, 255, NORM_MINMAX, CV_8U);
//   imshow("OUT", data.mMat[OUTP]);
//   imshow("Temp", tempLBP);
//   imshow("Inpu", inpuLBP);
//   waitKey();
}
