void CalibrationRecorder::processImage () {
  lastMarkerValid=false;
  double sensitivity = (static_cast<double>(panel->sensitivity)+100.0)/100.0;
  RGBTuple red = { 255,0,0 };
  RGBTuple green = { 0,255,0 };
  RGBTuple yellow = { 255,255,0 };
  RGBTuple blue = { 0,0,255 };
  Painter paint (*image);
  switch (mode) {
    case redScreen:
      setPixelsetAll (*regionBefore, image->getWidth(), image->getHeight());
      regionAfter->clear();
      findReddishPixels (*regionAfter, *image, sensitivity);
      drawPixelset (*image, *regionAfter, yellow);
      break;
    case greenScreen:
      regionWork->clear();
      regionAfter->clear();
      findGreenishPixels (*regionWork, *image, sensitivity);
      intersectSortedSets (*regionAfter, *regionBefore, *regionWork);
      drawPixelset (*image, *regionAfter, yellow);
      break;
    case blueScreen:
      regionWork->clear();
      regionAfter->clear();
      findBluishPixels (*regionWork, *image, sensitivity);
      intersectSortedSets (*regionAfter, *regionBefore, *regionWork);
      drawPixelset (*image, *regionAfter, yellow);
      break;
    case redMarker:
      regionWork->clear();
      regionAfter->clear();
      findReddishPixels (*regionWork, *image, sensitivity);
      intersectSortedSets (*regionAfter, *regionBefore, *regionWork);
      drawPixelset (*image, *regionAfter, yellow);
      gravityCenter = centerOfGravity (*regionAfter);
      if (gravityCenter.x==0 && gravityCenter.y==0)
        gravityCenter=Vec(-1000,-1000);  // fuer den Fall dass kein roter Bereich gefunden wurde
      paint.setColor (blue);
      paint.markCrosshair (static_cast<int>(gravityCenter.x+0.5), static_cast<int>(gravityCenter.y+0.5), 10);
      break;
    case blackMarker:
    {
      GrayLevelImage ggsrc (*image);
      std::deque<std::deque<ImageCoordinate> > lines;
      std::deque<std::deque<ImageCoordinate> > linesC;
      canny (lines, ggsrc, 5, 6, 20);
      for (unsigned int i=0; i<lines.size(); i++) {
        deque<unsigned int> breakpoints;
        breakLine (breakpoints, lines[i]);
        deque<deque<ImageCoordinate> > lines2;
        splitLineSorted (lines2, lines[i], breakpoints);
        for (unsigned int j=0; j<lines2.size(); j++) {
          if (lines2[j].size()>5) {
            deque<ImageCoordinate>::iterator it1=lines2[j].begin();
            deque<ImageCoordinate>::iterator it2=lines2[j].end();
            if (isAround (gravityCenter, 50, it1, it2)) {
              deque<ImageCoordinate> nl;
              linesC.push_back (nl);
              linesC.back().assign (it1, it2);
            }
          }
        }
      }
      if (linesC.size()>=4) {
        sort (linesC.begin(), linesC.end(), linelencomp);

        // beste Kombination der 4 Linien suchen
        unsigned int linesNum = (linesC.size()<8 ? linesC.size() : 8);
        Vec orientation [8];
        for (unsigned int i=0; i<linesNum; i++)
         orientation[i]=(linesC[i].front().toVec()-linesC[i].back().toVec()).normalize();

        unsigned int b1=99, b2=99, b3=99, b4=99;
        unsigned bestSolution = 1000;
        Vec intersection;
        for (unsigned int i1=0; i1<linesNum; i1++) {
          for (unsigned int i2=i1+1; i2<linesNum; i2++) {
            double orientationMatch1 = abs(orientation[i1]*orientation[i2]);
            if (orientationMatch1<0.5)
              continue; // Kanten sind mehr als 60Grad auseinander
            double minimalDistance1 = minDist (linesC[i1], linesC[i2], orientation[i1]*orientation[i2]);
            if (minimalDistance1>20)
              continue;  // Kanten sind zu weit voneinander entfernt
            std::deque<ImageCoordinate> pxl1 = linesC[i1];
            pxl1.insert (pxl1.end(), linesC[i2].begin(), linesC[i2].end());
            LineSegment ls1 = estimateLineSegment (pxl1.begin(), pxl1.end());
            Line l1 (ls1.getStart(), ls1.getEnd());
            Vec dir1 = (ls1.getStart()-ls1.getEnd()).normalize();
            for (unsigned int i3=0; i3<linesNum; i3++) if (i3!=i1 && i3!=i2) {
              for (unsigned int i4=i3+1; i4<linesNum; i4++) if (i4!=i1 && i4!=i2) {
                try{
                  double orientationMatch2 = abs(orientation[i3]*orientation[i4]);
                  if (orientationMatch1+orientationMatch2<1.5)
                    continue; // Kanten sind zu weit auseinander
                  double minimalDistance2 = minDist (linesC[i3], linesC[i4], orientation[i1]*orientation[i2]);
                  if (minimalDistance1+minimalDistance2>30)
                    continue;  // Kanten sind zu weit voneinander entfernt
                  std::deque<ImageCoordinate> pxl2 = linesC[i3];
                  pxl2.insert (pxl2.end(), linesC[i4].begin(), linesC[i4].end());
                  LineSegment ls2 = estimateLineSegment (pxl2.begin(), pxl2.end());
                  Line l2 (ls2.getStart(), ls2.getEnd());
                  Vec norm2 = (ls2.getStart()-ls2.getEnd()).normalize().rotate_quarter();
                  double mm = dir1*norm2;
                  if (mm<0.5)
                    continue;  // Kanten bilden kein Kreuz
                  Vec pi = intersect (l1, l2);
                  double md=1e300;
                  for (unsigned int i=0; i<regionAfter->size(); i++) {
                    double d=((*regionAfter)[i].toVec()-pi).length();
                    if (d<md)
                      md=d;
                  }
                  if (md>5)
                    continue;  // Punkt ausserhalb des roten Kreises
                  if (i1+i2+i3+i4<bestSolution) {
                    bestSolution=i1+i2+i3+i4;
                    intersection=pi;
                    b1=i1;
                    b2=i2;
                    b3=i3;
                    b4=i4;
                  }
                }catch(invalid_argument&){;}
              }
            }
          }
        }

        for (unsigned int i=0; i<linesC.size(); i++) {
          LineSegment ls = estimateLineSegment (linesC[i].begin(), linesC[i].end());
          bool sel = (i==b1 || i==b2 || i==b3 || i==b4);
          drawLine (*image, ls.getStart(), ls.getEnd(), (sel ? red : green), yellow);
        }

        if (bestSolution<1000) {
          cerr << "Schnittpunkt: " << intersection << endl;
          paint.setColor (blue);
          paint.markRect (static_cast<int>(intersection.x+0.5), static_cast<int>(intersection.y+0.5), 5);
          CalibrationMarker mk;
          mk.truePosition=trueMarkerPosition;
          mk.imagePosition=intersection;
          mk.imageNumber=imageNumber;
          markers.push_back (mk);
        } else {
          cerr << "Problem: die laengsten Linienstuecke bilden kein Kreuz\n";
        }
      } else {
        cerr << "Problem: nur " << linesC.size() << " Linienstuecke gefunden\n";
      }
      break;
    }
    default: // nothing, just display image
      break;
  }
}
Example #2
0
LineSegment<T, N> getReverse(const LineSegment<T, N>& line)
{
    return LineSegment<T, N>(line.getEnd(), line.getStart());
}