2018-05-26 18:09:38
先处理图像,滤去杂质,进行霍夫线变换,得到线段的序列,选择一根最长的线,这里简单处理,选择纵向最长的,进行角度的计算。 #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); CvPoint* line_p; for (int i = 0; i < lines_p->total; i++) { line_p = (CvPoint*)cvGetSeqElem(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: |
|
来自: 新用户79878317 > 《opencv求物体位置》