как найти крайнюю точку контура opencv c++

У меня есть это изображение:

введите здесь описание изображения

Как я могу реализовать код поиска экстремальных точек в OpenCv c++, как на картинке?

У кого-нибудь есть идеи, пожалуйста??

# determine the most extreme points along the contour

leftmost = tuple(cnt [cnt[:,:,0].argmin()][0]);
rightmost = tuple(cnt [cnt[:,:,0].argmax()][0]);
topmost = tuple(cnt [cnt[:,:,1].argmin()][0]);
bottommost = tuple(cnt [cnt[:,:,1].argmax()][0]);

person G.Rajesh    schedule 16.11.2017    source источник
comment
Я думаю, вы можете найти ответ в этом сообщении Найти крайние точки   -  person tuan.tran    schedule 16.11.2017
comment
Вы можете просто использовать std::minmax_element с лямбда-функцией. Один раз лямбда-функция должна сравнивать x, а другой раз — y. Или std::minmax, если вам нужны только баллы   -  person api55    schedule 16.11.2017


Ответы (2)


Предполагая, что у вас уже есть контур и он представляет собой вектор точек, вы можете использовать std: :minmax_element для того же конца. Он поддерживает метод сравнения, который может быть любым, если он следует за подписью. Итак, простой код, похожий на то, что вы делаете, будет:

#include <iostream>
#include <vector>
#include <algorithm>

// this is not necessary, just for testing (OpenCV Points should be used instead)
struct Point
{
    int x;
    int y;


    Point():
    x(0), y(0){}
    Point(int xVal, int yVal):
    x(xVal), y(yVal){}
};

int main()
{
    std::vector<Point> cnt = {
        {1,2},{4,5},{1,6}, {7,8}, {9,3}, {2,6}
    };

    // compare x axis
    auto val = std::minmax_element(cnt.begin(), cnt.end(), [](Point const& a, Point const& b){
        return a.x < b.x;
    });

    std::cout << " leftMost [ " << val.first->x << ", " << val.first->y << " ]" << std::endl;
    std::cout << " RightMost [ " << val.second->x << ", " << val.second->y << " ]" << std::endl;

    // compare y axis
    val = std::minmax_element(cnt.begin(), cnt.end(), [](Point const& a, Point const& b){
        return a.y < b.y;
    });

    std::cout << " TopMost [ " << val.first->x << ", " << val.first->y << " ]" << std::endl;
    std::cout << " BottomMost [ " << val.second->x << ", " << val.second->y << " ]" << std::endl;


    return 0;
}

Вот ссылка для его запуска.

В этом примере структура Point предназначена только для имитации OpenCV, но она будет работать точно так же. Я создаю тестовый вектор, запускаю minmax_element, сравнивая только ось x, и распечатываю результаты. Я делаю то же самое с осью y.

Эта функция возвращает пару итераторов к таким объектам, если вам нужно, чтобы они возвращались, обязательно скопируйте их :)

person api55    schedule 16.11.2017
comment
спасибо за ответ, но что, если мой вектор: вектор‹ вектор‹Точка› › контуры; для использования в роботизированных манипуляциях мне нужна эта крайняя точка как пиксель. - person G.Rajesh; 17.11.2017
comment
так как я должен использовать функцию :::findContours(temp, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);, чтобы найти тот же контур в реальном времени. показывает фатальную ошибку - person G.Rajesh; 17.11.2017
comment
Какая ошибка? отредактируйте свой вопрос (используйте кнопку редактирования под ним) и добавьте обновление к своему вопросу. Вы должны сделать это для contours[i]. contours - это вектор вектора точек, а функция работает с вектором точек, и вам нужно сначала проверить, есть ли у него точки, если нет, это даст ошибку. - person api55; 17.11.2017
comment
большое спасибо!! Моя проблема: когда я использую `вектор‹ вектор‹Точка› › контуры, ваша программа не работает. и когда я использую vector<Point> > contoursтолько мой findContours(temp, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); не работает - person G.Rajesh; 17.11.2017
comment
Код серьезности Описание Ошибка состояния подавления строки файла проекта (активно) E0312 нет подходящего определяемого пользователем преобразования из std::vector‹cv::Point, std::allocator‹cv::Point›› в cv::Point exists ql - person G.Rajesh; 17.11.2017
comment
Это означает, что вы передали vector<Point> там, где нужно было всего Point - person api55; 17.11.2017

void thresh_callback(int, void* )
{
    Mat canny_output;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;

    Canny( src_gray, canny_output, thresh, thresh*2, 3 );
    findContours( canny_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );

    Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );

    for( size_t i = 0; i< contours.size(); i++ )
    {
        Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
        drawContours( drawing, contours, (int)i, color, 2, 8, hierarchy, 0, Point() );
    }

    namedWindow( "Contours", WINDOW_AUTOSIZE );
    imshow( "Contours", drawing );
}

использовать этот код, как работает приведенный выше код

person G.Rajesh    schedule 17.11.2017