如何使用 OpenCV C++ 检测图像中有多少阶梯
How to detect how many stairs are there in an image using OpenCV C++
我正在尝试使用带有 C++ 的 OpenCV 来检测图像中有多少楼梯,我已经尝试这样做了:
1-二值化。
2-Canny 过滤器。
3-霍夫滤波器。
4-连通分量。
我没有得到好的结果,你知道我应该遵循哪种方法吗?
提前致谢。
这是一个图像示例。
我的算法就是这样;找到每个楼梯的线条将为我们提供楼梯编号。为此,可以使用 Houghline 变换。您应该阅读下面链接的文档,以便能够理解 HoughLinesP 函数的参数逻辑。
会遇到第一个问题: Houghline 变换会给你很多行。为了获得可用的线,我消除了 y 轴 值彼此接近的线。这个门槛我是通过考虑两个楼梯之间的最小距离来决定的。
注意:对垂直(90度)到楼梯拍摄的图像进行处理会得到更好的结果。
以下是这些步骤、结果和代码:
- 应用GauusianBlur to blur the image. The reason of GauusianBlur choosing instead of the 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 算法前:
算法后:
您可以获得如下有趣的结果:
水平计算像素总和;这将为您提供配置文件(一维信号);
计算轮廓的导数;
检测峰值;它们是正面的和负面的,或者,每一步一个。
我正在尝试使用带有 C++ 的 OpenCV 来检测图像中有多少楼梯,我已经尝试这样做了:
1-二值化。
2-Canny 过滤器。
3-霍夫滤波器。
4-连通分量。
我没有得到好的结果,你知道我应该遵循哪种方法吗?
提前致谢。
这是一个图像示例。
我的算法就是这样;找到每个楼梯的线条将为我们提供楼梯编号。为此,可以使用 Houghline 变换。您应该阅读下面链接的文档,以便能够理解 HoughLinesP 函数的参数逻辑。
会遇到第一个问题: Houghline 变换会给你很多行。为了获得可用的线,我消除了 y 轴 值彼此接近的线。这个门槛我是通过考虑两个楼梯之间的最小距离来决定的。
注意:对垂直(90度)到楼梯拍摄的图像进行处理会得到更好的结果。
以下是这些步骤、结果和代码:
- 应用GauusianBlur to blur the image. The reason of GauusianBlur choosing instead of the 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 算法前:
算法后:
您可以获得如下有趣的结果:
水平计算像素总和;这将为您提供配置文件(一维信号);
计算轮廓的导数;
检测峰值;它们是正面的和负面的,或者,每一步一个。