有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

用java对连接字符的图像进行分割

我试图在下图中的不同角色周围画一个边界框。但是,由于某些字符已连接,因此无法绘制方框。我试过一些东西,比如;扩张,侵蚀和尝试不同的模糊,但我似乎无法将它们分开。侵蚀似乎是接近的最佳方式,但如果我继续侵蚀,字符就无法识别

我使用Java中的OpenCV库来实现这一点

Mat img = Imgcodecs.imread("test.jpg");

        List<MatOfPoint> contours = new ArrayList<>();
        Mat hierarchy = new Mat();
        Imgproc.cvtColor(img, img, Imgproc.COLOR_BGR2GRAY);
        Imgproc.threshold(img, img, 220, 255, 0);
        Imgproc.erode(img, img, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3)));
        Imgproc.findContours(img, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE);


        MatOfPoint2f approxCurve = new MatOfPoint2f();

        //For each contour found
        for (int i = 0; i < contours.size(); i++) {
            MatOfPoint2f contour2f = new MatOfPoint2f(contours.get(i).toArray());
            double approxDistance = Imgproc.arcLength(contour2f, true) * 0.02;
            Imgproc.approxPolyDP(contour2f, approxCurve, approxDistance, true);

            MatOfPoint points = new MatOfPoint(approxCurve.toArray());

            Rect rect = Imgproc.boundingRect(points);
            Imgproc.rectangle(img, rect.tl(), rect.br(), new Scalar(255, 255, 255), 1, 8, 0);
        }
        System.out.println(img);
        Imgcodecs.imwrite("o.jpg", img);

之前:

https://i.imgur.com/qiTwfnx.png

之后:

https://i.imgur.com/ekjbWNs.png


共 (1) 个答案

  1. # 1 楼答案

    一种可能的方法(你可以尝试)是,如果你知道字符的数量,例如:5,那么你可以先在分割的轮廓周围绑定一个矩形,然后将宽度除以5,然后在图像上绘制黑色的矩形,然后图像将被成功分割

    按照以下步骤操作:

    cv::namedWindow("result", cv::WINDOW_FREERATIO);
    cv::Mat img = cv::imread(R"(D:\A49d6.png)");
    
    // to gray
    cv::Mat gray;
    cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
    // remove unvisible noise
    cv::threshold(gray, gray, 20, 255, cv::THRESH_BINARY);
    
    // this is to make sure to get the correct bounding rect
    cv::morphologyEx(gray, gray, cv::MORPH_CLOSE, cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(5, 1)));
    
    std::vector<std::vector<cv::Point> > contours;
    cv::findContours(gray, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
    
    // because we know that there is only one contour, so get the first posittion (0 index) from the list
    cv::Rect rect = cv::boundingRect(contours[0]);
    
    // calculate the width for each character
    int width = int(round(rect.width/5.0));
    for(int i(0); i<5; i++) {
        cv::Rect r(rect.x+(width*i), rect.y, width, rect.height);
        cv::rectangle(img, r, cv::Scalar(0));
    }
    
    cv::imshow("result", img);
    cv::waitKey();
    

    结果如下:

    enter image description here

    现在图像已经清晰到可以识别了