我正在尝试使用带有C++的OpenCV来检测图像中有多少阶梯,我试图这样做:
1-二值化。
2-Canny筛选器。
3-霍夫滤清器。
4个连接的组件。
我没有得到很好的结果,您对我应该采用哪种方法学有所了解吗?
先感谢您。
这是一个图像示例。
最佳答案
我的算法方法就是这样。找到每个楼梯的线会给我们楼梯号。为了实现 Houghline转换,可以使用。您应该阅读下面链接的文档,才能理解HoughLinesP函数的参数逻辑。
将会遇到第一个问题: Houghline变换将为您提供许多行。为了获得可用的行,我消除了 y轴值彼此接近的行。我通过考虑两个楼梯之间的最小距离来确定此阈值。
注意:要处理与楼梯垂直(90度)拍摄的图像,将获得更好的效果。
以下是这些步骤,结果和代码:
码:
#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:
后算法:
关于c++ - 如何使用OpenCV C++检测图像中有多少阶梯,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61602249/