【问题标题】:How to detect how many stairs are there in an image using OpenCV C++如何使用 OpenCV C++ 检测图像中有多少楼梯
【发布时间】:2020-08-19 11:17:58
【问题描述】:

我正在尝试使用 OpenCV 和 C++ 检测图像中有多少楼梯,我尝试过这样做:

1-二值化。

2-Canny 过滤器。

3-Hough 滤波器。

4-连接组件。

我没有得到好的结果,你知道我应该遵循哪种方法吗?

提前谢谢你。

这是一个图像示例。

【问题讨论】:

    标签: c++ image opencv image-processing image-segmentation


    【解决方案1】:

    我的算法方法就是这样;找到每个楼梯的线将为我们提供楼梯编号。为了实现这一点,可以使用 Houghline 变换。您应该阅读下面链接的文档以了解 HoughLinesP 函数的参数逻辑。

    第一个问题会遇到: Houghline 变换会给你很多线。为了获得可用的线条,我消除了 y 轴 值彼此接近的线条。我通过考虑两个楼梯之间的最小距离来确定这个阈值。

    注意:处理垂直(90 度)到楼梯拍摄的图像会得到更好的结果。

    以下是这些步骤、结果和代码:

    • 应用GauusianBlur 来模糊图像。选择 GausianBlur 而不是 others 的原因我认为 GaussianBlur 与 houghline transform 有很好的结合。
    • 申请Canny Edge detection
    • 将图像转换为 BGR 格式。
    • 申请HoughLinesP 并找到所有可能的行
    • 应用上述算法方法。
    • 获取结果。

    代码:

    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    #include <iostream>
    
    using namespace cv;
    using namespace std;
    
    int main()
    {
    
        Mat img = imread("/home/rnd/Desktop/photos/stairs.png");
        imshow("Source",img);
    
        //Apply Gaussian blur to get good results
        GaussianBlur(img,img,Size(5,5),0,0);
    
        Mat dst, out_img,control;
        Canny(img, dst, 80, 240, 3);
        cvtColor(dst, out_img, CV_GRAY2BGR);
        cvtColor(dst, control, CV_GRAY2BGR);
    
        vector<int> y_keeper_for_lines;
        vector<Vec4i> lines;
        HoughLinesP(dst, lines, 1, CV_PI/180, 30, 40, 5 );
    
        for( size_t i = 1; i < lines.size(); i++ )
        {
            Vec4i l = lines[i];
            line( control, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA);
        }
    
        Vec4i l = lines[0];
        line( out_img, Point(0, l[1]), Point(img.cols, l[1]), Scalar(0,0,255), 3, CV_AA);
        y_keeper_for_lines.push_back(l[1]);
    
        int okey = 1;
        int stair_counter = 1;
    
        for( size_t i = 1; i < lines.size(); i++ )
        {
            Vec4i l = lines[i];
            for(int m:y_keeper_for_lines)
            {
                if(abs(m-l[1])<15)
                    okey = 0;
    
            }
            if(okey)
            {
                line( out_img, Point(0, l[1]), Point(img.cols, l[1]), Scalar(0,0,255), 3, CV_AA);
                y_keeper_for_lines.push_back(l[1]);
                stair_counter++;
            }
            okey = 1;
    
        }
        putText(out_img,"Stair number:" + to_string(stair_counter),Point(40,60),FONT_HERSHEY_SIMPLEX,1.5,Scalar(0,255,0),2);
        imshow("Before", img);
        imshow("Control", control);
        imshow("detected lines", out_img);
        waitKey(0);
        return 0;
    }
    

    结果:

    高斯后:

    算法前的HoughLinesP:

    算法后:

    【讨论】:

    • 谢谢我的朋友!我是图像处理和计算机视觉领域的新手,你真的很有帮助!
    【解决方案2】:

    您可以获得如下有趣的结果:

    • 水平计算像素总和;这将为您提供轮廓(一维信号);

    • 计算轮廓的导数;

    • 检测峰值;它们是正面的和负面的,或者每个步骤一个。

    【讨论】:

    • 哇,我从来没想过这个方法!!迫不及待想试试!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 2023-03-05
    • 1970-01-01
    • 2017-01-02
    相关资源
    最近更新 更多