opencv简单的霍夫线变换应用,得到物体角度

 
 

先处理图像,滤去杂质,进行霍夫线变换,得到线段的序列,选择一根最长的线,这里简单处理,选择纵向最长的,进行角度的计算。

#include <iostream>
#include <opencv2/opencv.hpp>
#include <queue>
#include <math.h>

using namespace std;
using namespace cv;
int main()
{
	IplImage * g1 = cvLoadImage("倾斜的尺子.bmp", 1);//原图
	IplImage * g2 = cvCreateImage(cvSize(g1->width, g1->height), IPL_DEPTH_8U, 1);//存储灰度化后的图像
	IplImage * g3 = cvCreateImage(cvSize(g1->width, g1->height), IPL_DEPTH_8U, 1);//存储二值化、腐蚀、膨胀后的图像
	CvMemStorage* m_storage = cvCreateMemStorage(0);

	int length = 0;
	int maxTemp = 0;
	int maxLength = 0;
	double slope = 0;//斜率
	int tubeAngle = 0;//角度

	IplImage *dst = cvCloneImage(g1);//霍夫变换得到的直线画在dst上
	cvShowImage("原图", g1);
	cvCvtColor(g1, g2, CV_BGR2GRAY);//  转化为灰度图像
	cvAdaptiveThreshold(g2, g3, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 31);//自适应二值化
 	Mat gg3 = cv::cvarrToMat(g3);
	erode(gg3, gg3, Mat(2, 2, CV_8U), Point(-1, -1), 2);   //腐蚀
	dilate(gg3, gg3, Mat(2, 2, CV_8U), Point(-1, -1), 2);  //膨胀    腐蚀膨胀为了滤出噪声点而凸显目标

	cvShowImage("处理后的图像", g3);
	CvSeq* lines_p = cvHoughLines2(g3, m_storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI / 180, 30, 30, 10);

	cvZero(dst);cvGetSeqElem

	CvPoint* line_p;
	for (int i = 0; i < lines_p->total; i++)
	{
		line_p = (CvPoint*)(lines_p, i);
		cvLine(dst, line_p[0], line_p[1], CV_RGB(255, 255, 255), 2, CV_AA, 0);
		length = abs(line_p[0].y - line_p[1].y);
		if (i == 0)
		{
			maxLength = length;
		}
		else
		{
			if (length > maxLength)
			{
				maxTemp = i;//得到纵向最长的直线对应的序号
				maxLength = length;
			}
		}
	}

	cvShowImage("霍夫线变换得到的线", dst);
	line_p = (CvPoint*)cvGetSeqElem(lines_p, maxTemp);
	if (line_p != NULL)
	{
		if (line_p[0].x != line_p[1].x)
		{
			slope = abs((double)maxLength / (double)(line_p[0].x - line_p[1].x));
			tubeAngle = std::atan(slope) * 180 / 3.14159; 
		}
		else
			tubeAngle = 90;		
	}	
	cout << tubeAngle << endl;  
	waitKey();
	return 0;
}

结果如下:

 39度。

原图g1:


处理后的图像g3:


线变换得到的线段dst:


猜你喜欢

转载自blog.csdn.net/znzxc/article/details/80463424