我需要使用 opencvsharp 识别图像中的文本

Posted

技术标签:

【中文标题】我需要使用 opencvsharp 识别图像中的文本【英文标题】:I need recognize text in image using opencvsharp 【发布时间】:2015-12-19 00:48:05 【问题描述】:

我试图识别图像中的文本。

实际上我正在尝试识别图像中的文本位置,然后将其转换为文本。

我发现了一些用 c++ 编写的代码,我正在尝试将其转换为 c#。 你能帮帮我吗?

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;

我尝试将其转换为 c#,但没有成功

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】:

根据您要查找的文本大小,您可能需要使用元素大小和 ApproxPolyDP 的变量,但此代码非常接近原始代码,但使用的是 OpenCvSharp 术语。

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;

【讨论】:

以上是关于我需要使用 opencvsharp 识别图像中的文本的主要内容,如果未能解决你的问题,请参考以下文章

合并 MSER 中的区域以识别 OCR 中的文本行

如何在 Xamarin Forms 中打开图像并将其与 Emgu Cv/OpenCvSharp 一起使用?

使用 Python 和 OpenCV3 检测流程图中的文本区域

OpenCVSharp对图像进行颜色分割

opencvsharp_基于轮廓的形状匹配中匹配坐标与旋转角度

opencvsharp_基于轮廓的形状匹配中匹配坐标与旋转角度