[我正在尝试使用带有C ++的OpenCV来检测图像中有多少阶梯,我试图这样做:
1-二值化。
2-Canny筛选器。
3-霍夫过滤器。
4-连接的组件。
我没有得到好的结果,您对我应该采用哪种方法有任何想法吗?
先谢谢您。
这里是图像示例。
我的算法方法就是这样;找到每个楼梯的线会给我们楼梯号。为了实现Houghline Transform can。您应该阅读下面链接的文档,以了解HoughLinesP函数的参数逻辑。
第一个问题将会出现: Houghline变换将给您很多行。为了获得可用的行,我消除了y-axis值彼此接近的行。我通过考虑两个楼梯之间的最小距离来确定此阈值。
注意:要处理与楼梯垂直(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:
算法之后: