Перейти к содержимому
Compvision.ru

Доска почета


Popular Content

Showing most liked content on 30.07.2015 во всех областях

  1. 1 point
    Защитил диплом, забыл приложить финальный код, может кому пригодится. Большое спасибо Smorodov и всем отписавшимся. Считаются все необходимые параметры(коэффициент смещения колеса, делительная окружность, модуль колеса). При необходимости реализации масштаба, нужно домножить все параметры на коэффициент масштаба. #include "opencv2/opencv.hpp" #include <iostream> #include <vector> using namespace cv; using namespace std; int main(int ac, char** av) { vector<vector<Point> > contours; vector<Vec4i> hierarchy; vector<RotatedRect> minEllipse; vector<RotatedRect> minRect; string fname; float alpha = 20; if (ac > 1) { fname = av[1]; alpha = ::atof(av[2]); } else { cout << "Need filename!" << endl; cin.get(); return 0; } Mat frame = imread(fname); Mat drawing = frame.clone(); frame = 266 - frame; namedWindow("result"); cvtColor(frame, frame, cv::COLOR_BGR2GRAY); threshold(frame, frame, 1, 255, THRESH_BINARY); Mat thr = frame.clone(); /// Find contours findContours(frame, contours, hierarchy, cv::RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); vector<Point2f>center(contours.size()); vector<float>radius(contours.size()); vector<vector<Point> > contours_poly(contours.size()); for (int i = 0; i < contours.size(); i++) { approxPolyDP(Mat(contours[i]), contours_poly[i], 5, true); minEnclosingCircle((Mat)contours_poly[i], center[i], radius[i]); minRect.push_back(minAreaRect(Mat(contours[i]))); if (contours[i].size() > 5) { minEllipse.push_back(fitEllipse(Mat(contours[i]))); } } RNG rng(12345); for (int i = 0; i< contours.size(); i++) { Scalar color = Scalar(255, 0, 0); // contour drawContours(drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point()); // ellipse ellipse(drawing, minEllipse[i], color, 0, 8); // rotated rectangle Point2f rect_points[4]; minRect[i].points(rect_points); for (int j = 0; j < 4; j++) line(drawing, rect_points[j], rect_points[(j + 1) % 4], color, 1, 8); // окружность circle(drawing, center[i], cvRound(radius[i]), color, 1, 8, 0); // ÷ентр окружности line(drawing, cv::Point(center[i].x, 0), cv::Point(center[i].x, drawing.rows), Scalar(0, 0, 255)); line(drawing, cv::Point(0, center[i].y), cv::Point(drawing.cols, center[i].y), Scalar(0, 0, 255)); } // засемплим точки с окружности. float step = 0.001; float x = center[0].x; float y = center[0].y; float r = radius[0] * 0.9; Mat unrolled = Mat::zeros(100, CV_PI*2.0 / step, CV_8UC1); int i = 0; int tooth_thick = 0; vector<int> teeth; bool tooth = false; float normals[2][2]; for (float ang = 0; ang<CV_PI * 2; ang += step) { float xs = x + r*cos(ang); float ys = y + r*sin(ang); uchar c = thr.at<uchar>(ys, xs); drawing.at<Vec3b>(ys, xs) = Vec3b(0, 0, 255); if (c>128) { if (teeth.size() == 1 && tooth == false) { normals[0][0] = xs; normals[0][1] = ys; } tooth = true; tooth_thick++; line(unrolled, cv::Point(i, 0), cv::Point(i, unrolled.rows), Scalar::all(255),5); } else { if (tooth) { teeth.push_back(tooth_thick); tooth_thick = 0; //count++; if (teeth.size() == 1) { normals[1][0] = xs; normals[1][1] = ys; } } tooth = false; } ++i; } //do normals to surface of teeth //line(drawing, Point(normals[0][0], normals[0][1]), Point(800 * cos(alpha * 180 / CV_PI), normals[0][1] * sin(alpha * 180 / CV_PI)), Scalar(0, 255, 0), 1); //line(drawing, Point(normals[1][0], normals[1][1]), Point(800 * cos(alpha * 180 / CV_PI), normals[1][1] * sin(alpha * 180 / CV_PI)), Scalar(0, 255, 0), 1); float m = minRect[0].size.width/(teeth.size()+2);//модуль float d = m*teeth.size();//delitelnaya okrujnost float Db = d*::cos(alpha); float sb = (CV_PI*m) / 2; //tolshina po delitelnoy okrujnosti alpha = alpha * CV_PI / 180;//for invol (convert deg to radian) float X = ((normals[0][1] - normals[1][1]) - (Db*(sb / d + (tan(alpha)-alpha)))) / (2 * m*sin(alpha)); stringstream str; str << "d= " + to_string(minRect[0].size.width) << " "; str << "m= " + to_string(m) << " "; str << "x= " + to_string(X) << " "; //imshow("thr", thr); //imshow("unrolled", unrolled); Mat pic = cv::Mat::zeros(250, 250, CV_8UC3); putText(pic,str.str(), cv::Point(5, 10), CV_FONT_NORMAL, 0.3, Scalar::all(255), 1, 7, false); imshow("Результаты", pic); imshow("result", drawing); waitKey(0); destroyAllWindows(); return 0; }
×