MBOOL
SImager::
execute(MUINT32 const u4TimeoutMs)
{
    FUNCTION_LOG_START;
    //
    if (!isSupportedSrcFormat(mSrcImgBufInfo.eImgFmt)) 
    {
        MY_LOGE("Unsupport source format:0x%x", mSrcImgBufInfo.eImgFmt); 
        return MFALSE; 
    }   

    MUINT32 u4Width = mTargetImgInfo.u4ImgWidth; 
    MUINT32 u4Height = mTargetImgInfo.u4ImgHeight; 
    // rotation 
    if(90 == mTargetImgInfo.u4Rotation || 270 == mTargetImgInfo.u4Rotation)
    {
        u4Width = mTargetImgInfo.u4ImgHeight; 
        u4Height = mTargetImgInfo.u4ImgWidth; 
    }

    // stride 
    mTargetImgInfo.u4Stride[0] = (~(mu4StrideAlign[0]-1)) & ((mu4StrideAlign[0]-1) + NSCamShot::queryImgStride(mTargetImgInfo.eImgFmt, u4Width, 0)); 
    mTargetImgInfo.u4Stride[1] = (~(mu4StrideAlign[1]-1)) & ((mu4StrideAlign[1]-1) + NSCamShot::queryImgStride(mTargetImgInfo.eImgFmt, u4Width, 1)); 
    mTargetImgInfo.u4Stride[2] = (~(mu4StrideAlign[2]-1)) & ((mu4StrideAlign[2]-1) + NSCamShot::queryImgStride(mTargetImgInfo.eImgFmt, u4Width, 2)); 

    MY_LOGD("fmt = 0x%x, stride = (%d, %d, %d)", mTargetImgInfo.eImgFmt, mTargetImgInfo.u4Stride[0], mTargetImgInfo.u4Stride[1], mTargetImgInfo.u4Stride[2]); 
    MY_LOGD("(width, height) = (%d, %d)", u4Width, u4Height); 

    ImgBufInfo rTargetImgBuf(ImgInfo(mTargetImgInfo.eImgFmt, u4Width, u4Height), 
                        BufInfo(mTargetBufInfo), mTargetImgInfo.u4Stride); 

    if (mTargetImgInfo.eImgFmt == eImgFmt_JPEG)
    {
        encode(mSrcImgBufInfo, rTargetImgBuf, mTargetImgInfo.rROI, mTargetImgInfo.u4Rotation, mTargetImgInfo.u4Flip, mTargetImgInfo.u4Quality, mTargetImgInfo.u4IsSOI, mu4JpegSize);
    }
    else 
    {
        imgTransform(mSrcImgBufInfo, rTargetImgBuf, mTargetImgInfo.rROI, mTargetImgInfo.u4Rotation, mTargetImgInfo.u4Flip, u4TimeoutMs);    
    }

    FUNCTION_LOG_END;
     //
    return MTRUE;
}
示例#2
0
  std::vector<cv::Point2f> EdgeFinder::findEdgeCorners() {

    TextLineCollection tlc(pipeline_data->textLines);

    vector<Point> corners;

    // If the character segment is especially small, just expand the existing box
    // If it's a nice, long segment, then guess the correct box based on character height/position
    if (tlc.longerSegment.length > tlc.charHeight * 3)
    {
      float charHeightToPlateWidthRatio = pipeline_data->config->plateWidthMM / pipeline_data->config->charHeightMM;
      float idealPixelWidth = tlc.charHeight *  (charHeightToPlateWidthRatio * 1.03);	// Add 3% so we don't clip any characters

      float charHeightToPlateHeightRatio = pipeline_data->config->plateHeightMM / pipeline_data->config->charHeightMM;
      float idealPixelHeight = tlc.charHeight *  charHeightToPlateHeightRatio;


      float verticalOffset = (idealPixelHeight * 1.5 / 2);
      float horizontalOffset = (idealPixelWidth * 1.25 / 2);
      LineSegment topLine = tlc.centerHorizontalLine.getParallelLine(verticalOffset);
      LineSegment bottomLine = tlc.centerHorizontalLine.getParallelLine(-1 * verticalOffset);

      LineSegment leftLine = tlc.centerVerticalLine.getParallelLine(-1 * horizontalOffset);
      LineSegment rightLine = tlc.centerVerticalLine.getParallelLine(horizontalOffset);

      Point topLeft = topLine.intersection(leftLine);
      Point topRight = topLine.intersection(rightLine);
      Point botRight = bottomLine.intersection(rightLine);
      Point botLeft = bottomLine.intersection(leftLine);

      corners.push_back(topLeft);
      corners.push_back(topRight);
      corners.push_back(botRight);
      corners.push_back(botLeft);
    }
    else
    {

      //cout << "HEYOOO!" << endl;
      int expandX = (int) ((float) pipeline_data->crop_gray.cols) * 0.15f;
      int expandY = (int) ((float) pipeline_data->crop_gray.rows) * 0.15f;
      int w = pipeline_data->crop_gray.cols;
      int h = pipeline_data->crop_gray.rows;

      corners.push_back(Point(-1 * expandX, -1 * expandY));
      corners.push_back(Point(expandX + w, -1 * expandY));
      corners.push_back(Point(expandX + w, expandY + h));
      corners.push_back(Point(-1 * expandX, expandY + h));

  //    for (int i = 0; i < 4; i++)
  //    {
  //      std::cout << "CORNER: " << corners[i].x << " - " << corners[i].y << std::endl;
  //    }
    }

    // Re-crop an image (from the original image) using the new coordinates
    Transformation imgTransform(pipeline_data->grayImg, pipeline_data->crop_gray, pipeline_data->regionOfInterest);
    vector<Point2f> remappedCorners = imgTransform.transformSmallPointsToBigImage(corners);

    Size cropSize = imgTransform.getCropSize(remappedCorners, 
            Size(pipeline_data->config->templateWidthPx, pipeline_data->config->templateHeightPx));

    Mat transmtx = imgTransform.getTransformationMatrix(remappedCorners, cropSize);
    Mat newCrop = imgTransform.crop(cropSize, transmtx);

    // Re-map the textline coordinates to the new crop  
    vector<TextLine> newLines;
    for (unsigned int i = 0; i < pipeline_data->textLines.size(); i++)
    {        
      vector<Point2f> textArea = imgTransform.transformSmallPointsToBigImage(pipeline_data->textLines[i].textArea);
      vector<Point2f> linePolygon = imgTransform.transformSmallPointsToBigImage(pipeline_data->textLines[i].linePolygon);

      vector<Point2f> textAreaRemapped;
      vector<Point2f> linePolygonRemapped;

      textAreaRemapped = imgTransform.remapSmallPointstoCrop(textArea, transmtx);
      linePolygonRemapped = imgTransform.remapSmallPointstoCrop(linePolygon, transmtx);

      newLines.push_back(TextLine(textAreaRemapped, linePolygonRemapped));
    }

    // Find the PlateLines for this crop
    PlateLines plateLines(pipeline_data);
    plateLines.processImage(newCrop, newLines, 1.05);

    // Get the best corners
    PlateCorners cornerFinder(newCrop, &plateLines, pipeline_data, newLines);
    vector<Point> smallPlateCorners = cornerFinder.findPlateCorners();

    confidence = cornerFinder.confidence;

    // Transform the best corner points back to the original image
    std::vector<Point2f> imgArea;
    imgArea.push_back(Point2f(0, 0));
    imgArea.push_back(Point2f(newCrop.cols, 0));
    imgArea.push_back(Point2f(newCrop.cols, newCrop.rows));
    imgArea.push_back(Point2f(0, newCrop.rows));
    Mat newCropTransmtx = imgTransform.getTransformationMatrix(imgArea, remappedCorners);

    vector<Point2f> cornersInOriginalImg = imgTransform.remapSmallPointstoCrop(smallPlateCorners, newCropTransmtx);

    return cornersInOriginalImg;

  }
示例#3
0
  // Must delete this pointer in parent class
  void LicensePlateCandidate::recognize()
  {
    charSegmenter = NULL;

    pipeline_data->plate_area_confidence = 0;
    pipeline_data->isMultiline = config->multiline;


    Rect expandedRegion = this->pipeline_data->regionOfInterest;

    pipeline_data->crop_gray = Mat(this->pipeline_data->grayImg, expandedRegion);
    resize(pipeline_data->crop_gray, pipeline_data->crop_gray, Size(config->templateWidthPx, config->templateHeightPx));


    CharacterAnalysis textAnalysis(pipeline_data);

    if (textAnalysis.confidence > 10)
    {

      EdgeFinder edgeFinder(pipeline_data);

      pipeline_data->plate_corners = edgeFinder.findEdgeCorners();

      if (edgeFinder.confidence > 0)
      {

        timespec startTime;
        getTime(&startTime);


        Mat originalCrop = pipeline_data->crop_gray;

        Transformation imgTransform(this->pipeline_data->grayImg, pipeline_data->crop_gray, expandedRegion);

        Size cropSize = imgTransform.getCropSize(pipeline_data->plate_corners, 
                Size(pipeline_data->config->ocrImageWidthPx, pipeline_data->config->ocrImageHeightPx));
        Mat transmtx = imgTransform.getTransformationMatrix(pipeline_data->plate_corners, cropSize);
        pipeline_data->crop_gray = imgTransform.crop(cropSize, transmtx);


        if (this->config->debugGeneral)
          displayImage(config, "quadrilateral", pipeline_data->crop_gray);



        // Apply a perspective transformation to the TextLine objects
        // to match the newly deskewed license plate crop
        vector<TextLine> newLines;
        for (unsigned int i = 0; i < pipeline_data->textLines.size(); i++)
        {        
          vector<Point2f> textArea = imgTransform.transformSmallPointsToBigImage(pipeline_data->textLines[i].textArea);
          vector<Point2f> linePolygon = imgTransform.transformSmallPointsToBigImage(pipeline_data->textLines[i].linePolygon);

          vector<Point2f> textAreaRemapped;
          vector<Point2f> linePolygonRemapped;

          textAreaRemapped = imgTransform.remapSmallPointstoCrop(textArea, transmtx);
          linePolygonRemapped = imgTransform.remapSmallPointstoCrop(linePolygon, transmtx);

          newLines.push_back(TextLine(textAreaRemapped, linePolygonRemapped));
        }

        pipeline_data->textLines.clear();
        for (unsigned int i = 0; i < newLines.size(); i++)
          pipeline_data->textLines.push_back(newLines[i]);



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

        charSegmenter = new CharacterSegmenter(pipeline_data);


        pipeline_data->plate_area_confidence = 100;
      }

    }
  }