C++ 如何删除canny图像中的直线或非曲线

C++ 如何删除canny图像中的直线或非曲线,c++,opencv,image-processing,image-segmentation,canny-operator,C++,Opencv,Image Processing,Image Segmentation,Canny Operator,我有一个精明的边缘图像 我想删除所有线条,除了看起来像半圆/椭圆或“C”的线条。尝试了Hough圆变换,它可以检测所有曲线。不需要。一个简单的方法是: 查找连接的组件 找到最小定向边界框 计算长方体的纵横比,并检查它是否过长 在你的照片上,我用红色标出了几乎是直线,用绿色标出了曲线。您可以在纵横比上使用阈值: 代码: #包括 使用名称空间cv; int main() { //加载图像 Mat1b img=imread(“路径到img”,imread\U灰度); //创建输出图像 Mat3b输

我有一个精明的边缘图像


我想删除所有线条,除了看起来像半圆/椭圆或“C”的线条。尝试了Hough圆变换,它可以检测所有曲线。不需要。一个简单的方法是:

  • 查找连接的组件
  • 找到最小定向边界框
  • 计算长方体的纵横比,并检查它是否过长
  • 在你的照片上,我用红色标出了几乎是直线,用绿色标出了曲线。您可以在纵横比上使用阈值:

    代码:

    #包括
    使用名称空间cv;
    int main()
    {
    //加载图像
    Mat1b img=imread(“路径到img”,imread\U灰度);
    //创建输出图像
    Mat3b输出;
    CVT颜色(img、out、COLOR_GRAY2BGR);
    //寻找轮廓
    矢量等值线;
    findContours(img.clone()、轮廓、检索列表、链近似值无);
    用于(常量自动和等高线:等高线)
    {
    //查找最小面积矩形
    RotatedRect rr=MinareRect(轮廓);
    //计算纵横比
    浮动纵横比=最小值(rr.size.WITH,rr.size.height)/最大值(rr.size.WITH,rr.size.height);
    //在[0,1]中定义纵横比阈值
    浮动脱粒=0.2f;
    Vec3b颜色;
    如果(纵横比<阈值){
    //几乎直线
    颜色=Vec3b(0,0255);//红色
    }
    否则{
    //曲线
    color=Vec3b(0,255,0);//绿色
    }
    //彩色输出图像
    用于(常数自动和pt:轮廓){
    输出(pt)=颜色;
    }
    }
    imshow(“Out”,Out);
    waitKey();
    返回0;
    }
    
    一个简单的方法是:

  • 查找连接的组件
  • 找到最小定向边界框
  • 计算长方体的纵横比,并检查它是否过长
  • 在你的照片上,我用红色标出了几乎是直线,用绿色标出了曲线。您可以在纵横比上使用阈值:

    代码:

    #包括
    使用名称空间cv;
    int main()
    {
    //加载图像
    Mat1b img=imread(“路径到img”,imread\U灰度);
    //创建输出图像
    Mat3b输出;
    CVT颜色(img、out、COLOR_GRAY2BGR);
    //寻找轮廓
    矢量等值线;
    findContours(img.clone()、轮廓、检索列表、链近似值无);
    用于(常量自动和等高线:等高线)
    {
    //查找最小面积矩形
    RotatedRect rr=MinareRect(轮廓);
    //计算纵横比
    浮动纵横比=最小值(rr.size.WITH,rr.size.height)/最大值(rr.size.WITH,rr.size.height);
    //在[0,1]中定义纵横比阈值
    浮动脱粒=0.2f;
    Vec3b颜色;
    如果(纵横比<阈值){
    //几乎直线
    颜色=Vec3b(0,0255);//红色
    }
    否则{
    //曲线
    color=Vec3b(0,255,0);//绿色
    }
    //彩色输出图像
    用于(常数自动和pt:轮廓){
    输出(pt)=颜色;
    }
    }
    imshow(“Out”,Out);
    waitKey();
    返回0;
    }
    
  • 从边缘找到轮廓
  • 获取边界框
  • 计算边界框对角线大小与轮廓大小的比率
  • 对于直边,此值将接近“1”。该比率的值越高,边的弯曲度就越大。它可以粗略但相当准确地估计边缘的卷曲度

    快乐编码

  • 从边缘找到轮廓
  • 获取边界框
  • 计算边界框对角线大小与轮廓大小的比率
  • 对于直边,此值将接近“1”。该比率的值越高,边的弯曲度就越大。它可以粗略但相当准确地估计边缘的卷曲度


    快乐编码

    1。尝试提取每个连接的组件。2.试着检测它是否是“直的”。例如,使用PCA并比较两个主成分。1.尝试提取每个连接的组件。2.试着检测它是否是“直的”。例如,使用PCA并比较两个主成分。
    #include<opencv2/opencv.hpp>
    using namespace cv;
    
    
    int main()
    {
        // Load image
        Mat1b img = imread("path_to_img", IMREAD_GRAYSCALE);
    
        // Create output image
        Mat3b out;
        cvtColor(img, out, COLOR_GRAY2BGR);
    
        // Find contours
        vector<vector<Point>> contours;
        findContours(img.clone(), contours, RETR_LIST, CHAIN_APPROX_NONE);
    
        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 = 0.2f;
    
            Vec3b color;
            if (aspect_ratio < thresh) { 
                // Almost straight line
                color = Vec3b(0,0,255); // RED
            }
            else {
                // Curved line
                color = Vec3b(0, 255, 0); // GREEN
            }
    
            // Color output image
            for (const auto& pt : contour) {
                out(pt) = color;
            }
        }
    
        imshow("Out", out);
        waitKey();
    
        return 0;
    }