Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

problem adaptiveThreshold

hi i have a problem with adaptiveThreshold, i have this error:

OpenCV Error: Assertion failed (src.type() == CV_8UC1) in adaptiveThreshold, file /home/petrucci/opencv-3.1.0/modules/imgproc/src/thresh.cpp, line 1286
terminate called after throwing an instance of 'cv::Exception'
  what():  /home/petrucci/opencv-3.1.0/modules/imgproc/src/thresh.cpp:1286: error: (-215) src.type() == CV_8UC1 in function adaptiveThreshold

the code is:

void cb(uvc_frame_t *frame, void *data) {
  cv::Mat cvFrame(frame->height, frame->width, CV_16UC1, frame->data);
  j++;
  puts("frame");
  ostringstream ss;
        ss << "Image" << j <<"g"<<gain<<".jpg";

        string filename = ss.str();
        imwrite(filename.c_str(),cvFrame);

        Mat image;
        image = imread(filename);
  puts("frame salvato");
  trackFrame((TrackingData*)(data), image);
}



#include "eyetracking.h"

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/photo/photo.hpp>
#include <iostream>
#include <chrono>
#include <utility>

#include "halideFuncs.h"
#include "starburst.h"

static const int kFirstGlintXShadow = 100;
static const int kGlintNeighbourhood = 100;
static const int kEyeRegionWidth = 200;
static const int kEyeRegionHeight = 160;
static const double k8BitScale = (265.0/1024.0)*2.0;

using namespace cv;

struct TrackingData {
  HalideGens *gens;
  TrackingData() {
    gens = createGens();
  }
  ~TrackingData() {
    deleteGens(gens);
  }
};

// search for other set pixels in an area around the point and find the average of the set locations
static Point findLocalCenter(Mat &m, Point p, int size) {
  int xSum = 0;
  int ySum = 0;
  int count = 0;
  for(int i = std::max(0,p.y-size); i < std::min(m.rows,p.y+size); i++) {
    const uint8_t* Mi = m.ptr<uint8_t>(i);
    for(int j = std::max(0,p.x-size); j < std::min(m.cols,p.x+size); j++) {
      if(Mi[j] == 0) {
        xSum += j; ySum += i;
        count += 1;
      }
    }
  }
  if(count == 0) return Point(0,0);
  return Point(xSum/count, ySum/count);
}

static std::vector<Point> trackGlints(TrackingData *dat, Mat &m) {
  // double maxVal;
  // Point maxPt;
  // minMaxLoc(m, nullptr, &maxVal, nullptr, &maxPt);
  // std::cout << "max val: " << maxVal << " at " << maxPt << std::endl;
  // threshold(m, m, maxVal*kGlintThreshold, 255, THRESH_BINARY_INV);
  // adaptiveThreshold(m, m, 1, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 11, -10.0);
  adaptiveThreshold(m, m, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY_INV, 11, -40.0);

  // search for first two pixels separated sufficiently horizontally
  // start from the top and only take the first two so that glints off of teeth and headphones are ignored.
  std::vector<Point> result;
  for(int i = 0; i < m.rows; i++) {
    if(result.size() >= 2) break;
    const uint8_t* Mi = m.ptr<uint8_t>(i);
    for(int j = 0; j < m.cols; j++) {
      if(Mi[j] == 0) {
        if(result.empty()) {
          result.push_back(Point(j,i));
        } else if(j > result[0].x+kFirstGlintXShadow || j < result[0].x-kFirstGlintXShadow) {
          result.push_back(Point(j,i));
          break;
        }
      }
    }
  }
  // Make the found point more centered on the eye instead of being just the first one
  for(auto &&p : result)
    p = findLocalCenter(m,p, kGlintNeighbourhood);

  // consistent order, purely so debug views aren't jittery
  std::sort(result.begin(), result.end(), [](Point a, Point b) {
      return a.x < b.x;
  });

  return result;
}

void trackFrame(TrackingData *dat, Mat &bigM) {
  std::chrono::time_point<std::chrono::high_resolution_clock> start, end;
  start = std::chrono::high_resolution_clock::now();

  // fix stuck pixel on my EyeTribe by pasting over it
  // TODO: don't enable this for everyone else
  bigM.at<uint16_t>(283,627) = bigM.at<uint16_t>(283,626);

  Mat m;
  resize(bigM, m, Size(bigM.cols/2,bigM.rows/2));

  Mat glintImage;
  m.convertTo(glintImage, CV_8U, 256.0/1024.0);
  // glintImage = glintKernel(dat->gens, m);
  auto glints = trackGlints(dat, glintImage);
  Mat foundGlints = findGlints(dat->gens, glintImage);


  for(unsigned i = 0; i < glints.size(); ++i) {
    // project onto big image
    Rect smallRoi = Rect(glints[i].x-(kEyeRegionWidth/4),glints[i].y-(kEyeRegionHeight/4),kEyeRegionWidth/2,kEyeRegionHeight/2) & Rect(0,0,m.cols,m.rows);
    Rect roi = Rect(glints[i].x*2-(kEyeRegionWidth/2),glints[i].y*2-(kEyeRegionHeight/2),kEyeRegionWidth,kEyeRegionHeight) & Rect(0,0,bigM.cols,bigM.rows);
    Mat region(bigM, roi);
    // Mat region(m, smallRoi);
    region.convertTo(region, CV_8U, k8BitScale, 0);
    // imshow(std::to_string(i)+"_raw", region);
    blur(region, region, Size(3,3));

    // inpaint over the glints so they don't mess up further stages
    Mat glintMask = Mat(glintImage, smallRoi).clone();
    threshold(glintMask, glintMask, 0, 255, THRESH_BINARY_INV); // invert mask
    dilate(glintMask, glintMask, getStructuringElement(MORPH_RECT, Size(4,4))); // without this it inpaints white
    resize(glintMask, glintMask, roi.size());
    inpaint(region, glintMask, region, 4, INPAINT_NS);

    findEllipseStarburst(region, std::to_string(i));
  }

  end = std::chrono::high_resolution_clock::now();
  std::cout << "elapsed time: " << std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count() << "ms\n";

  m.convertTo(m, CV_8U, k8BitScale, 0);
  Mat channels[3];
  channels[1] = m;
  channels[0] = channels[2] = min(m, glintImage);
  Mat debugImage;
  merge(channels,3,debugImage);
  // debugImage = glintImage;

  for(auto glint : glints)
    circle(debugImage, glint, 3, Scalar(255,0,255));

  imshow("main", debugImage);
}

TrackingData *setupTracking() {
  cv::namedWindow("main",CV_WINDOW_NORMAL);
  cv::namedWindow("0",CV_WINDOW_NORMAL);
  cv::namedWindow("1",CV_WINDOW_NORMAL);
  cv::namedWindow("0_polar",CV_WINDOW_NORMAL);
  cv::namedWindow("1_polar",CV_WINDOW_NORMAL);
  cv::moveWindow("main", 600, 600);
  cv::moveWindow("0", 400, 50);
  cv::moveWindow("1", 600, 50);
  cv::moveWindow("0_polar", 400, 300);
  cv::moveWindow("1_polar", 600, 300);
  // cv::namedWindow("glint",CV_WINDOW_NORMAL);
  createTrackbar("Starburst thresh", "main", &starThresh, 180);
  createTrackbar("Starburst rays", "main", &starRays, 80);
  return new TrackingData();
}