I need recognize text in image using opencvsharp

2019-09-11 04:58发布

I trying to identify text in an image.

Actually I'm trying to identify the text positions in the image then convert it to text.

I found a some code written on c++ and I am trying to convert it to c#. Can you help me please?

Extracting text OpenCV

std::vector<cv::Rect> detectLetters(cv::Mat img)
{       std::vector<cv::Rect> boundRect;[enter image description here][1]
    cv::Mat img_gray, img_sobel, img_threshold, element;
    cvtColor(img, img_gray, CV_BGR2GRAY);
    cv::Sobel(img_gray, img_sobel, CV_8U, 1, 0, 3, 1, 0, cv::BORDER_DEFAULT);
    cv::threshold(img_sobel, img_threshold, 0, 255, CV_THRESH_OTSU+CV_THRESH_BINARY);
    element = getStructuringElement(cv::MORPH_RECT, cv::Size(10, 15) );
    cv::morphologyEx(img_threshold, img_threshold, CV_MOP_CLOSE, element); //Does the trick
    std::vector< std::vector< cv::Point> > contours;
    cv::findContours(img_threshold, contours, 0, 1); 
    std::vector<std::vector<cv::Point> > contours_poly( contours.size() );
    for( int i = 0; i < contours.size(); i++ )
        if (contours[i].size()>80)
        { 
            cv::approxPolyDP( cv::Mat(contours[i]), contours_poly[i], 17, true );
            cv::Rect appRect( boundingRect( cv::Mat(contours_poly[i]) ));
            if (appRect.width>appRect.height) 
                boundRect.push_back(appRect);
        }
        return boundRect;
}

and i try to convert it to c#, but it didn't work

private List<Rectangle> detectLetters(IntPtr img)
{
    //cvtColor(img, img_gray, CV_BGR2GRAY);
    List<Rectangle> boundRect = new List<Rectangle>();

    //cv::Mat img_gray, img_sobel, img_threshold, element;
    IntPtr 
        img_gray = IntPtr.Zero, 
        img_sobel= IntPtr.Zero, 
        img_threshold= IntPtr.Zero,
        img_tmp = IntPtr.Zero,
        element= IntPtr.Zero;

    //cvtColor(img, img_gray, CV_BGR2GRAY);
    CvInvoke.cvCvtColor(img, img_gray,COLOR_CONVERSION.CV_BGR2GRAY); //CV_BGR2GRAY);

    //cv::Sobel(img_gray, img_sobel, CV_8U, 1, 0, 3, 1, 0, cv::BORDER_DEFAULT);
    CvInvoke.cvSobel(img_gray, img_sobel, 0, 1, 1);//, 3, 1, 0, cv.BORDER_DEFAULT);

    //cv.threshold(img_sobel, img_threshold, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);
    CvInvoke.cvThreshold(img_sobel, img_threshold, 0, 255, THRESH.CV_THRESH_BINARY|THRESH.CV_THRESH_OTSU);

    //element = getStructuringElement(cv.MORPH_RECT, cv.Size(10, 15));
    element = CvInvoke.cvCreateStructuringElementEx(1,1,10,15,CV_ELEMENT_SHAPE.CV_SHAPE_RECT,element);// GetStructuringElement(

    //cv.morphologyEx(img_threshold, img_threshold, CV_MOP_CLOSE, element); //Does the trick
    CvInvoke.cvMorphologyEx(img_threshold,img_threshold,img_tmp,element,CV_MORPH_OP.CV_MOP_CLOSE,1);

    //List<List<cv.Point>> contours = new List<List<cv.Point>>();
    var contours = new List<IntPtr>();

    //cv.findContours(img_threshold, contours, 0, 1);
    CvInvoke.cvFindContours(img_threshold, element,ref ((IntPtr)contours[0]), 1, RETR_TYPE.CV_RETR_EXTERNAL, CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE,new Point(0,0));


    //std::vector<std::vector<cv::Point> > contours_poly( contours.size() );
    var contours_poly = new List<List<Point>>(contours.Count);

    //for( int i = 0; i < contours.size(); i++ )
    for (int i = 0; i < contours.Count; i++)
    {
        //if (contours[i].size()>80)
        if (contours[i].ToInt32() > 80)
        {
            //cv.approxPolyDP(Emgu.CV.Matrix<>(contours[i]), contours_poly[i], 17, true);
            CvInvoke.cvApproxPoly(contours[i], 17,contours_poly[i],APPROX_POLY_TYPE.CV_POLY_APPROX_DP, 1,1);
            //cv::Rect appRect( boundingRect( cv::Mat(contours_poly[i]) ));
            Rectangle appRect = new Rectangle(CvInvoke.cvBoundingRect(contours_poly[i],false));
            //if (appRect.width>appRect.height) 
            if (appRect.width > appRect.height)
            {
                //boundRect.push_back(appRect);
                boundRect.Add(appRect);
            }
        }
    }
    //return boundRect;
    return boundRect;
}

1条回答
倾城 Initia
2楼-- · 2019-09-11 05:25

Depending on what the size of the text you're looking for, you may have to play around with the variables for element size and ApproxPolyDP but this code is pretty close to the original but in OpenCvSharp lingo.

static List<Rect> RunTextRecog(string inFile)
{
    List<Rect> boundRect = new List<Rect>();
    using (Mat img = new Mat(inFile))
    using (Mat img_gray = new Mat())
    using (Mat img_sobel = new Mat())
    using (Mat img_threshold = new Mat())
    {
        Cv2.CvtColor(img, img_gray, ColorConversionCodes.BGR2GRAY);
        Cv2.Sobel(img_gray, img_sobel, MatType.CV_8U, 1, 0, 3, 1, 0, BorderTypes.Default);
        Cv2.Threshold(img_sobel, img_threshold, 0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary);
        using (Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(10, 15)))
        {
            Cv2.MorphologyEx(img_threshold, img_threshold, MorphTypes.Close, element);
            Point[][] edgesArray = img_threshold.Clone().FindContoursAsArray(RetrievalModes.External, ContourApproximationModes.ApproxNone);
            foreach (Point[] edges in edgesArray)
            {
                Point[] normalizedEdges = Cv2.ApproxPolyDP(edges, 17, true);
                Rect appRect = Cv2.BoundingRect(normalizedEdges);
                boundRect.Add(appRect);
            }
        }
    }
    return boundRect;
}
查看更多
登录 后发表回答