【问题标题】:How to remove long edges in a canny edge image?如何去除精巧边缘图像中的长边缘?
【发布时间】:2016-10-19 09:23:10
【问题描述】:

处理精明边缘检测后,我得到边缘图像。 但我只想保持短边(边缘来自角色)。 并且有一些长边(这里我定义为超过图片高度的一半)。示例图片如下所示:

那么如何去除超过图片一半高度的边缘?

相关问题: remove horizontal/vertical long edges

【问题讨论】:

    标签: image opencv canny-operator


    【解决方案1】:

    您可以对包含边缘的minAreaRect 应用一些约束。 你可以找到一个例子here,但是由于你的边缘接触到了边框,你需要一个额外的技巧来让findContours正常工作,所以下面是改进的代码。

    通过对纵横比的简单约束,您可以得到:

    您删除了 红色 边缘的位置:

    您可以添加额外的约束,例如在height 上,以满足您的特定目的。

    代码如下:

    #include<opencv2/opencv.hpp>
    using namespace cv;
    
    
    int main()
    {
        // Load image
        Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);
    
        // Remove JPG artifacts
        img = img > 200;
    
        Mat1b result = img.clone();
    
        // Create output image
        Mat3b out;
        cvtColor(img, out, COLOR_GRAY2BGR);
    
        // Find contours
        Mat1b padded;
        copyMakeBorder(img, padded, 1, 1, 1, 1, BORDER_CONSTANT, Scalar(0));
        vector<vector<Point>> contours;
        findContours(padded, contours, RETR_LIST, CHAIN_APPROX_NONE, Point(-1, -1));
    
        for (const auto& contour : contours)
        {
            // Find minimum area rectangle
            RotatedRect rr = minAreaRect(contour);
    
            // Compute aspect ratio
            float aspect_ratio = min(rr.size.width, rr.size.height) / max(rr.size.width, rr.size.height);
    
            // Define a threshold on the aspect ratio in [0, 1]
            float thresh_ar = 0.05f;
    
            // Define other constraints
    
            bool remove = false;
            if (aspect_ratio < thresh_ar) {
                remove = true;
            }
    
            // if(some_other_constraint) { remove = true; }
    
            Vec3b color;
            if (remove) {
                // Almost straight line
                color = Vec3b(0, 0, 255); // RED
    
                // Delete edge
                for (const auto& pt : contour) {
                    result(pt) = uchar(0);
                }
            }
            else {
                // Curved line
                color = Vec3b(0, 255, 0); // GREEN
            }
    
            // Color output image
            for (const auto& pt : contour) {
                out(pt) = color;
            }
        }
    
        imshow("Out", out);
        imshow("Result", result);
        waitKey();
    
        return 0;
    }
    

    【讨论】:

    • 太棒了!感谢您的解决方案。你能给我一些关于如何去除我不需要的其他边缘的建议(比如右边的边缘,但它们不够长)?
    • 稍微增加thresh_ar,例如至 0.075 或 0.1。对字母的最大高度进行一些限制......像这样......它确实特定于您的上下文。只有边缘可以去除一些噪音,但你需要更强大的东西来去除除了你的字母之外的所有东西
    • 非常感谢。我会试试看的!
    猜你喜欢
    • 2020-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 2020-12-02
    • 2012-07-09
    • 2022-01-07
    相关资源
    最近更新 更多