Image 如何删除canny边缘图像中的长边?

Image 如何删除canny边缘图像中的长边?,image,opencv,canny-operator,Image,Opencv,Canny Operator,经过canny边缘检测,得到边缘图像。 但我只想保留短边(边来自角色)。 还有一些长边(这里我定义的长边超过图片高度的一半)。示例图片如下所示: 那么,我如何才能删除跨越图片高度一半以上的边缘呢 相关问题: 您可以对包含边的minareact应用一些约束。 您可以找到一个示例,但由于您的边与边界接触,因此需要额外的技巧才能使findContours正常工作,因此在改进的代码下面 通过对纵横比的简单约束,可以得到: 删除红色边的位置: 您可以添加额外的约束,例如在高度上添加约束,以满足您的特

经过canny边缘检测,得到边缘图像。 但我只想保留短边(边来自角色)。 还有一些长边(这里我定义的长边超过图片高度的一半)。示例图片如下所示:

那么,我如何才能删除跨越图片高度一半以上的边缘呢

相关问题:

您可以对包含边的
minareact
应用一些约束。 您可以找到一个示例,但由于您的边与边界接触,因此需要额外的技巧才能使
findContours
正常工作,因此在改进的代码下面

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

删除红色边的位置:

您可以添加额外的约束,例如在
高度上添加约束,以满足您的特定用途

代码如下:

#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;
}
#包括
使用名称空间cv;
int main()
{
//加载图像
Mat1b img=imread(“路径到图像”,imread\U灰度);
//删除JPG工件
img=img>200;
Mat1b result=img.clone();
//创建输出图像
Mat3b输出;
CVT颜色(img、out、COLOR_GRAY2BGR);
//寻找轮廓
Mat1b填充;
copyMakeBorder(img,填充,1,1,1,1,BORDER_常量,标量(0));
矢量等值线;
findContours(填充、轮廓、修复列表、链约无、点(-1,-1));
用于(常量自动和等高线:等高线)
{
//查找最小面积矩形
RotatedRect rr=MinareRect(轮廓);
//计算纵横比
浮动纵横比=最小值(rr.size.WITH,rr.size.height)/最大值(rr.size.WITH,rr.size.height);
//在[0,1]中定义纵横比阈值
浮动阈值=0.05f;
//定义其他约束
bool-remove=false;
if(纵横比<阈值){
移除=真;
}
//如果(某些其他约束){remove=true;}
Vec3b颜色;
如果(删除){
//几乎直线
颜色=Vec3b(0,0,255);//红色
//删除边
用于(常数自动和pt:轮廓){
结果(pt)=uchar(0);
}
}
否则{
//曲线
color=Vec3b(0,255,0);//绿色
}
//彩色输出图像
用于(常数自动和pt:轮廓){
输出(pt)=颜色;
}
}
imshow(“Out”,Out);
imshow(“结果”,Result);
waitKey();
返回0;
}

您可以对包含边的
minareact
应用一些约束。 您可以找到一个示例,但由于您的边与边界接触,因此需要额外的技巧才能使
findContours
正常工作,因此在改进的代码下面

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

删除红色边的位置:

您可以添加额外的约束,例如在
高度上添加约束,以满足您的特定用途

代码如下:

#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;
}
#包括
使用名称空间cv;
int main()
{
//加载图像
Mat1b img=imread(“路径到图像”,imread\U灰度);
//删除JPG工件
img=img>200;
Mat1b result=img.clone();
//创建输出图像
Mat3b输出;
CVT颜色(img、out、COLOR_GRAY2BGR);
//寻找轮廓
Mat1b填充;
copyMakeBorder(img,填充,1,1,1,1,BORDER_常量,标量(0));
矢量等值线;
findContours(填充、轮廓、修复列表、链约无、点(-1,-1));
用于(常量自动和等高线:等高线)
{
//查找最小面积矩形
RotatedRect rr=MinareRect(轮廓);
//计算纵横比
浮动纵横比=最小值(rr.size.WITH,rr.size.height)/最大值(rr.size.WITH,rr.size.height);
//在[0,1]中定义纵横比阈值
浮动阈值=0.05f;
//定义其他约束
bool-remove=false;
if(纵横比<阈值){
移除=真;
}
//如果(某些其他约束){remove=true;}
Vec3b颜色;
如果(删除){
//几乎直线
颜色=Vec3b(0,0,255);//红色
//删除边
用于(常数自动和pt:轮廓){
结果(pt)=uchar(0);
}
}
否则{
//曲线
color=Vec3b(0,255,0);//绿色
}
//彩色输出图像
用于(常数自动和pt:轮廓){
输出(pt)=颜色;
}
}
imshow(“Out”,Out);
imshow(“结果”,Result);
waitKey();
返回0;
}

太棒了!谢谢你的解决方案。您能给我一些建议,告诉我如何删除我不需要的其他边(例如右侧的边,但它们不够长)?稍微增加
阈值,例如,到0.075或0.1。在字母的最大高度上加上一些约束。。。像这样的。。这确实是特定于您的上下文的。只有边缘,你可以去除一些噪音,但你需要更强大的东西来去除除你的字母外的所有噪音。我要试试看!伟大的谢谢你的解决方案。您能给我一些建议,告诉我如何删除我不需要的其他边(例如右侧的边,但它们不够长)?稍微增加
阈值,例如,到0.075或0.1。在字母的最大高度上加上一些约束。。。像这样的。。这确实是特定于您的上下文的。只有边缘,你可以去除一些噪音,但你需要更强大的东西来去除除你的字母外的所有噪音。我要试试看!