Пример #1
0
void ChollaCurve::debug_draw()
{
  icolor++;
  icolor = icolor%15;
  dcolor(icolor);
  dldraw(curveEdgeList);
}
Пример #2
0
void ChollaSurface::debug_draw()
{
  icolor++;
  icolor = (icolor%15)+1;
  dcolor(icolor);
  dldraw(surfaceElemList);
}
Пример #3
0
//==================================================================================
//Function:  skin_2d  (PUBLIC)
//Description:  creates a skin of the given mesh entities.
//==================================================================================
CubitStatus ChollaSkinTool::skin_2d(DLIList<FacetEntity*> &facet_list,
                                   ChollaSurface *&facet_surface_mesh_ptr)
{
  if(facet_list.size() == 0){
    return CUBIT_SUCCESS;
  }
  
  int debugflag=0;
  if (debugflag)
  {
    dcolor(CUBIT_YELLOW);
    dldraw( facet_list );
    dview();
    dcolor(CUBIT_RED);
  }
  CubitStatus rv = CUBIT_SUCCESS;
  int block_id;

  // create a ChollaSurface if we have to (only if this is a 2D model)

  FacetEntity *face_ptr = facet_list.get();
  TDGeomFacet *td_gm = TDGeomFacet::get_geom_facet( face_ptr );
  block_id = td_gm->get_block_id();
  if (!facet_surface_mesh_ptr)
  {
    facet_surface_mesh_ptr = new ChollaSurface(block_id);

    // associate all of the tooldata on the faces of this surf with the new ChollaSurface

    int ii;
    for (ii=0; ii<facet_list.size(); ii++)
    {
      face_ptr = facet_list.get_and_step();
      facet_surface_mesh_ptr->add_facet( face_ptr );
      td_gm = TDGeomFacet::get_geom_facet( face_ptr );
      td_gm->add_cholla_surf( facet_surface_mesh_ptr );
      td_gm->set_hit_flag( facet_surface_mesh_ptr->get_id() );
    }
  }

  // create a single ChollaCurve for this surface (assumes one loop of edges)

  ChollaCurve *fcm_ptr = new ChollaCurve( block_id );
  facet_surface_mesh_ptr->add_curve( fcm_ptr );
  fcm_ptr->add_surface( facet_surface_mesh_ptr );

  // loop through all faces on this surface searching for the boundary edges

  int jj, kk, ll;
  for ( kk = 0; kk < facet_list.size(); kk++)
  {
    face_ptr = facet_list.get_and_step();
    DLIList<CubitFacetEdge*> edge_list;
    face_ptr->edges( edge_list );

    // loop through each edge on this face searching for boundary edges

    for (jj=edge_list.size(); jj > 0; jj--)
    {
      CubitFacetEdge *edge_ptr = edge_list.get_and_step();

      // check if this edge has already been processed from an adjacent surface.
      // If it has, then tool data would have already been defined at this edge
      // and by definition would be at the boundary (only tooldatas on edges
      // at the boundary ofa surface are created)

      TDGeomFacet *td_gm_edge = TDGeomFacet::get_geom_facet(edge_ptr);
      int on_boundary = 0;
      if (td_gm_edge != NULL)
      { 
        on_boundary = 1;

        // check for internal C-zero edge

        if (edge_ptr->num_adj_facets() == 2)
        {
          TDFacetBoundaryEdge *td_fbe = 
            TDFacetBoundaryEdge::get_facet_boundary_edge( edge_ptr );
          if (td_fbe != NULL)
          {
            if (td_fbe->is_internal_edge())
            {
              on_boundary = 0;
            }
          }
        } 
      }

      // check for general case where no tool data yet defined

      else 
      {
        DLIList<FacetEntity*> adj_face_list;

        // check the adjacent faces to this edge.  If only one adjacent face, then
        // it is on the boundary.  If more than one face, then the other face(s)
        // must be associated with a surface other than facet_surface_mesh_ptr
        // in order to be on the boundary

        edge_ptr->get_parents( adj_face_list );
        if (adj_face_list.size() <= 1)
        {
          on_boundary = 1;
        }
        else
        {
          for (ll=adj_face_list.size(); ll> 0 && !on_boundary; ll--)
          {
            FacetEntity *adj_face_ptr = adj_face_list.get_and_step();
            if (adj_face_ptr != face_ptr)
            {
              TDGeomFacet *td_gm_adjface = TDGeomFacet::get_geom_facet(adj_face_ptr);
              DLIList<ChollaSurface*> surf_list;
              td_gm_adjface->get_cholla_surfs( surf_list );

              // if it doesn't have an associated surface yet, then it is 
              // a neighboring surface that has not been defined yet (this
              // should only occur for the 2D case)
                       
              if (surf_list.size() == 0)
              {
                on_boundary = 1;
              }
              else
              {

                // there should only be one surface associated with
                // each face - otherwise we've screwed up somewhere  

                assert ( surf_list.size() == 1 );

                // if the surface is not the same as the current surface
                // then we are at the boundary

                ChollaSurface *check_bsm_ptr = surf_list.get();
                if (facet_surface_mesh_ptr != check_bsm_ptr)
                {
                  on_boundary = 1;
                }
              }
            }
          }
        }
      }
      if (on_boundary)
      {
        // create a tool data if needed

        if (td_gm_edge == NULL)
        {
          TDGeomFacet::add_geom_facet(edge_ptr, -1); 
          td_gm_edge = TDGeomFacet::get_geom_facet( edge_ptr );
          edge_ptr->set_as_feature();
        }

        // add the pointer to this surface onto the edge tool data

        td_gm_edge->add_cholla_surf( facet_surface_mesh_ptr );

        // add this edge to the curve

        fcm_ptr->add_facet( edge_ptr );
        if (mydebug)
          dedraw(edge_ptr);
      }
    }
  }

  return rv;
}
Пример #4
0
  void CharacterAnalysis::analyze()
  {
    timespec startTime;
    getTimeMonotonic(&startTime);

    pipeline_data->clearThresholds();
    pipeline_data->thresholds = produceThresholds(pipeline_data->crop_gray, config);

    timespec contoursStartTime;
    getTimeMonotonic(&contoursStartTime);

    pipeline_data->textLines.clear();

    for (unsigned int i = 0; i < pipeline_data->thresholds.size(); i++)
    {
      TextContours tc(pipeline_data->thresholds[i]);

      allTextContours.push_back(tc);
    }

    if (config->debugTiming)
    {
      timespec contoursEndTime;
      getTimeMonotonic(&contoursEndTime);
      cout << "  -- Character Analysis Find Contours Time: " << diffclock(contoursStartTime, contoursEndTime) << "ms." << endl;
    }
    //Mat img_equalized = equalizeBrightness(img_gray);

    timespec filterStartTime;
    getTimeMonotonic(&filterStartTime);

    for (unsigned int i = 0; i < pipeline_data->thresholds.size(); i++)
    {
      this->filter(pipeline_data->thresholds[i], allTextContours[i]);

      if (config->debugCharAnalysis)
        cout << "Threshold " << i << " had " << allTextContours[i].getGoodIndicesCount() << " good indices." << endl;
    }

    if (config->debugTiming)
    {
      timespec filterEndTime;
      getTimeMonotonic(&filterEndTime);
      cout << "  -- Character Analysis Filter Time: " << diffclock(filterStartTime, filterEndTime) << "ms." << endl;
    }

    PlateMask plateMask(pipeline_data);
    plateMask.findOuterBoxMask(allTextContours);

    pipeline_data->hasPlateBorder = plateMask.hasPlateMask;
    pipeline_data->plateBorderMask = plateMask.getMask();

    if (plateMask.hasPlateMask)
    {
      // Filter out bad contours now that we have an outer box mask...
      for (unsigned int i = 0; i < pipeline_data->thresholds.size(); i++)
      {
        filterByOuterMask(allTextContours[i]);
      }
    }

    int bestFitScore = -1;
    int bestFitIndex = -1;
    for (unsigned int i = 0; i < pipeline_data->thresholds.size(); i++)
    {

      int segmentCount = allTextContours[i].getGoodIndicesCount();

      if (segmentCount > bestFitScore)
      {
        bestFitScore = segmentCount;
        bestFitIndex = i;
        bestThreshold = pipeline_data->thresholds[i];
        bestContours = allTextContours[i];
      }
    }

    if (this->config->debugCharAnalysis)
      cout << "Best fit score: " << bestFitScore << " Index: " << bestFitIndex << endl;

    if (bestFitScore <= 1)
    {
      pipeline_data->disqualified = true;
      pipeline_data->disqualify_reason = "Low best fit score in characteranalysis";
      return;
    }

    //getColorMask(img, allContours, allHierarchy, charSegments);

    if (this->config->debugCharAnalysis)
    {
      Mat img_contours = bestContours.drawDebugImage(bestThreshold);

      displayImage(config, "Matching Contours", img_contours);
    }

    LineFinder lf(pipeline_data);
    vector<vector<Point> > linePolygons = lf.findLines(pipeline_data->crop_gray, bestContours);

    vector<TextLine> tempTextLines;
    for (unsigned int i = 0; i < linePolygons.size(); i++)
    {
      vector<Point> linePolygon = linePolygons[i];

      LineSegment topLine = LineSegment(linePolygon[0].x, linePolygon[0].y, linePolygon[1].x, linePolygon[1].y);
      LineSegment bottomLine = LineSegment(linePolygon[3].x, linePolygon[3].y, linePolygon[2].x, linePolygon[2].y);

      vector<Point> textArea = getCharArea(topLine, bottomLine);

      TextLine textLine(textArea, linePolygon, pipeline_data->crop_gray.size());

      tempTextLines.push_back(textLine);
    }

    filterBetweenLines(bestThreshold, bestContours, tempTextLines);

    // Sort the lines from top to bottom.
    std::sort(tempTextLines.begin(), tempTextLines.end(), sort_text_line);

    // Now that we've filtered a few more contours, re-do the text area.
    for (unsigned int i = 0; i < tempTextLines.size(); i++)
    {
      vector<Point> updatedTextArea = getCharArea(tempTextLines[i].topLine, tempTextLines[i].bottomLine);
      vector<Point> linePolygon = tempTextLines[i].linePolygon;
      if (updatedTextArea.size() > 0 && linePolygon.size() > 0)
      {
        pipeline_data->textLines.push_back(TextLine(updatedTextArea, linePolygon, pipeline_data->crop_gray.size()));
      }

    }

    pipeline_data->plate_inverted = isPlateInverted();


    if (pipeline_data->textLines.size() > 0)
    {
      int confidenceDrainers = 0;
      int charSegmentCount = this->bestContours.getGoodIndicesCount();
      if (charSegmentCount == 1)
        confidenceDrainers += 91;
      else if (charSegmentCount < 5)
        confidenceDrainers += (5 - charSegmentCount) * 10;

      // Use the angle for the first line -- assume they'll always be parallel for multi-line plates
      int absangle = abs(pipeline_data->textLines[0].topLine.angle);
      if (absangle > config->maxPlateAngleDegrees)
        confidenceDrainers += 91;
      else if (absangle > 1)
        confidenceDrainers += (config->maxPlateAngleDegrees - absangle) ;

      // If a multiline plate has only one line, disqualify
      if (pipeline_data->isMultiline && pipeline_data->textLines.size() < 2)
      {
        if (config->debugCharAnalysis)
          std::cout << "Did not detect multiple lines on multi-line plate" << std::endl;
        confidenceDrainers += 95;
      }

      if (confidenceDrainers >= 90)
      {
        pipeline_data->disqualified = true;
        pipeline_data->disqualify_reason = "Low confidence in characteranalysis";
      }
      else
      {
        float confidence = 100 - confidenceDrainers;
        pipeline_data->confidence_weights.setScore("CHARACTER_ANALYSIS_SCORE", confidence, 1.0);
      }
    }
    else
    {
        pipeline_data->disqualified = true;
        pipeline_data->disqualify_reason = "No text lines found in characteranalysis";
    }

    if (config->debugTiming)
    {
      timespec endTime;
      getTimeMonotonic(&endTime);
      cout << "Character Analysis Time: " << diffclock(startTime, endTime) << "ms." << endl;
    }

    // Draw debug dashboard
    if (this->pipeline_data->config->debugCharAnalysis && pipeline_data->textLines.size() > 0)
    {
      vector<Mat> tempDash;
      for (unsigned int z = 0; z < pipeline_data->thresholds.size(); z++)
      {
        Mat tmp(pipeline_data->thresholds[z].size(), pipeline_data->thresholds[z].type());
        pipeline_data->thresholds[z].copyTo(tmp);
        cvtColor(tmp, tmp, CV_GRAY2BGR);

        tempDash.push_back(tmp);
      }

      Mat bestVal(this->bestThreshold.size(), this->bestThreshold.type());
      this->bestThreshold.copyTo(bestVal);
      cvtColor(bestVal, bestVal, CV_GRAY2BGR);

      for (unsigned int z = 0; z < this->bestContours.size(); z++)
      {
        Scalar dcolor(255,0,0);
        if (this->bestContours.goodIndices[z])
          dcolor = Scalar(0,255,0);
        drawContours(bestVal, this->bestContours.contours, z, dcolor, 1);
      }
      tempDash.push_back(bestVal);
      displayImage(config, "Character Region Step 1 Thresholds", drawImageDashboard(tempDash, bestVal.type(), 3));
    }
  }