Нахождение и рисование линии от центра фигуры до ближайшего края - PullRequest
0 голосов
/ 22 апреля 2019

Я новичок в программировании (учусь Бьярне. С. книга), начал изучать C ++ и OpenCV.У меня есть проект для работы, поэтому я пропустил много глав, чтобы понять обнаружение края.Я застрял в поиске ближайшей линии к краю обнаруженной фигуры.На самом деле я взял пример кода с сайта OpenCV: https://docs.opencv.org/4.1.0/d0/d49/tutorial_moments.html

Хотя я немного понимаю, но не могу реализовать такой код.Я искал вопрос такого рода, но не смог найти здесь или что-то еще.

#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <iomanip>

using namespace cv;
using namespace std;

Mat src_gray;
int thresh = 100;
RNG rng(12345);

/// Function header
void thresh_callback(int, void*);


int main(int argc, char** argv)
{
    /// Load source image
    CommandLineParser parser(argc, argv, "{@input | circles_rectangles.jpg | input image}");
    Mat src = imread(parser.get<String>("@input"));

    if (src.empty())
    {
        cout << "Could not open or find the image!\n" << endl;
        cout << "usage: " << argv[0] << " <Input image>" << endl;
        return -1;
    }

    /// Convert image to gray and blur it
    cvtColor(src, src_gray, COLOR_BGR2GRAY);
    blur(src_gray, src_gray, Size(3, 3));

    /// Create Window
    const char* source_window = "Source";
    namedWindow(source_window);
    imshow(source_window, src);

    const int max_thresh = 255;
    createTrackbar("Canny thresh:", source_window, &thresh, max_thresh, thresh_callback);
    thresh_callback(0, 0);

    waitKey();
    return 0;
}

/**
 * @function thresh_callback
 */
void thresh_callback(int, void*)
{
    /// Detect edges using canny
    Mat canny_output;
    Canny(src_gray, canny_output, thresh, thresh * 2, 3);
    /// Find contours
    vector<vector<Point> > contours;
    findContours(canny_output, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

    /// Get the moments
    vector<Moments> mu(contours.size());
    for (size_t i = 0; i < contours.size(); i++)
    {
        mu[i] = moments(contours[i]);
    }

    ///  Get the mass centers
    vector<Point2f> mc(contours.size());
    for (size_t i = 0; i < contours.size(); i++)
    {
        //add 1e-5 to avoid division by zero
        mc[i] = Point2f(static_cast<float>(mu[i].m10 / (mu[i].m00 + 1e-5)),
            static_cast<float>(mu[i].m01 / (mu[i].m00 + 1e-5)));
        cout << "mc[" << i << "]=" << mc[i] << endl;
    }

    /// Draw contours
    Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
    for (size_t i = 0; i < contours.size(); i++)
    {
        Scalar color = Scalar(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
        drawContours(drawing, contours, (int)i, color, 2);
        circle(drawing, mc[i], 4, color, -1);
    }

    /// Show in a window
    imshow("Contours and center", drawing);

    /// Calculate the area with the moments 00 and compare with the result of the OpenCV function
    cout << "\t Info: Area and Contour Length \n";
    for (size_t i = 0; i < contours.size(); i++)
    {
        cout << " * Contour[" << i << "] - Area (M_00) = " << std::fixed << std::setprecision(2) << mu[i].m00
            << " - Area OpenCV: " << contourArea(contours[i]) << " - Length: " << arcLength(contours[i], true) << endl;
    }
}

Вот изображение для отладки: https://imgur.com/Ymbu48a

Вот отлаженная версия: https://imgur.com/AFE9ZB1

И вот что я ожидаю сделать: https://imgur.com/MUfxikI

Есть предложения, как это сделать?

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