Как измерить угол прямоугольного маркера на вращающейся плоскости с помощью угловой камеры? - PullRequest
0 голосов
/ 05 декабря 2018

Я занимаюсь разработкой приложения.В этом приложении есть прямоугольный красный объект на вращающейся плоской поверхности.Я могу точно обнаружить этот красный объект.Я поворачиваю его на 10 градусов и измеряю, сколько градусов камера делает снова и снова. Но я видел широкий разброс значений углов, которые я измерил, когда камера смотрела под углом к ​​поверхности.

Я использовал openCv методы findHomography () и warpPerspective (), чтобы исправить это, но я не получил точного результата, который хотел.Поскольку эти два метода после того, как мы взяли 4 точки и вставили эти точки всегда в одну и ту же точку, которую я определил.

Интересно, можем ли мы сделать что-то подобное в соответствии с углом, на который смотрит камера, вы можетеЗафиксируйте форму прямоугольника во всей картине, например, краям прямоугольника можно присвоить градусы «A» от x, градусы «B» от y и «C» от ​​z, но он также будет поддерживать степень угла скамера?Тогда я буду измерять угол в выпрямленном прямоугольнике.Короче говоря, мне нужно исправить прямоугольник в соответствии с углом наклона камеры и измерить угол наклона прямоугольника относительно камеры.Но я не знаю, как далеко стоит камера.Я должен сделать это в целом изображении, а не в одном объекте ..

Спасибо за вашу помощь ...

Я поделюсь некоторым кодом и изображениями

`for (int getKey = 0; getKey < 36; getKey++)
    {
        ret = turnMotor("btnSetActPosZero", "true");
        Sleep(1000);

        ret = turnMotor("btnAbsMove", "true");
        Sleep(3000);


        for (int imageCnt = 0; key != 'q', imageCnt < dongu; imageCnt++)
        {
            // Get the image
            Image rawImage;
            t_error = t_camera.RetrieveBuffer(&rawImage);
            if (t_error != PGRERROR_OK) { t_error.PrintErrorTrace(); return -1; }

            Image rgbImage;
            rawImage.Convert(FlyCapture2::PIXEL_FORMAT_BGR, &rgbImage);

            cv::Mat imageUndistorted;
            unsigned int rowBytes = (double)rgbImage.GetReceivedDataSize() / (double)rgbImage.GetRows();
            cv::Mat image = cv::Mat(rgbImage.GetRows(), rgbImage.GetCols(), CV_8UC3, rgbImage.GetData(), rowBytes);
            cv::Mat res = image.clone();

            cv::initUndistortRectifyMap(intrinsic, distCoeffs, cv::Mat(), intrinsic, cv::Size(image.cols, image.rows), CV_32FC1, map1, map2);
            cv::remap(image, imageUndistorted, map1, map2, cv::INTER_CUBIC);
            cv::Mat imageI = cv::Mat(imageUndistorted, bbox);

            // Split eye image into 3 channels.
            vector<Mat>bgr(3);
            split(imageI, bgr);

            float angleRefAngleKirmizi = 0.0;

            {
                cv::Mat mask = (bgr[0] > 160) & (bgr[1] > 175);
                vector<vector<cv::Point> > contours;
                vector<cv::Vec4i> hierarchy;

                cv::Mat maskRedBefore = (bgr[2] > 175);

                Mat maskRed = maskRedBefore - mask;
                int index = 0;
                for (int i = 0; i < 4; i++)
                {
                    index = 0;
                    findContours(maskRed, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
                    if (contours.size() == 0) { return -1; };

                    double maxArea = contourArea(contours[0]);
                    int index = 0;
                    for (int i = 0; i < contours.size(); i++)
                    {
                        if (contourArea(contours[i]) > maxArea) {
                            maxArea = contourArea(contours[i]);
                            index = i;
                        }
                    }
                    floodFill(maskRed, Point(0, 0), Scalar(255, 255, 255));
                    drawContours(maskRed, contours, index, cv::Scalar(0, 255, 0), 1, 8, vector<cv::Vec4i>(), 0, cv::Point());
                    floodFill(maskRed, contours[index][int(contours[index].size() / 2)], Scalar(0, 0, 0));
                    floodFill(maskRed, Point(0, 0), Scalar(0, 0, 0));

                }

                Mat mask2;
                cv::Vec4f myLine;
                vector<cv::Point> nonZeroCoordinates;
                cv::findNonZero(maskRed, nonZeroCoordinates);

                if (nonZeroCoordinates.size() != 0)
                {
                    cv::fitLine(nonZeroCoordinates, myLine, CV_DIST_L2, 0, 0.01, 0.01);
                    angleRefAngleKirmizi = atan2(myLine[1], myLine[0]) < 0 ? atan2(myLine[1], myLine[0]) + CV_PI : atan2(myLine[1], myLine[0]);

                    cv::putText(imageI, to_string(angleRefAngleKirmizi * 180 / CV_PI), cv::Point(myLine[2], myLine[3]), cv::FONT_HERSHEY_SCRIPT_SIMPLEX, 0.3, cvScalar(0, 255, 255), 1, CV_AA);
                    line(imageI, cv::Point(myLine[2], myLine[3]), cv::Point(myLine[2] + myLine[0] * 100, myLine[3] + myLine[1] * 100), cv::Scalar(255, 0, 0), 1, 8);

                    out_transform << to_string(angleRefAngleKirmizi * 180 / CV_PI) << endl;
                }

            }

            imshow("image", imageI);
            key = cv::waitKey(1);
        }
`

и составные изображения прямоугольника смоделированы в некоторых отношениях. показано, что сочетание изображений прямоугольника под некоторыми углами и вращающейся плоской поверхности показывают вращающейся плоской поверхности

, а также добавить код, который выполняет два метода opencv.

            vector<cv::Point2d> approx;
            approxPolyDP(cv::Mat(contours[index]), approx, 3, true);

            if (approx.size() == 0) return -14;
            for (int j = 0; j < approx.size(); j++)
            {
                cv::putText(imageI, to_string(j), approx[j], cv::FONT_HERSHEY_SCRIPT_SIMPLEX, 0.6, cvScalar(0, 0, 0), 1, CV_AA);
                line(imageI, approx[j], approx[(j+1)% approx.size()], cv::Scalar(0, 0, 0), 1, 8);

            }


            vector<Point2f> pts_src;
            pts_src.push_back(Point2f(0, 0));
            pts_src.push_back(Point2f(80, 0));
            pts_src.push_back(Point2f(80, 30));
            pts_src.push_back(Point2f(0, 30));


            // Calculate Homography between source and destination points
            Mat h = findHomography(approx, pts_src);

            // Warp source image
            warpPerspective(imageI, HomogImage, h, HomogImage.size(), CV_INTER_LINEAR);
...