OpenCV, jak używać tablic punktów do konturów wygładzania i próbkowania?

Mam problem z opanowaniem konturów wygładzania i próbkowania w OpenCV (C ++ API). Powiedzmy, że mam sekwencję pobranych punktówcv::findContours (na przykład zastosowane na tym obrazie:

W końcu chcę

Wygładzanie sekwencji punktów przy użyciu różnych jąder.Aby zmienić rozmiar sekwencji przy użyciu różnych typów interpolacji.

Po wygładzeniu mam nadzieję, że wynik będzie taki jak:

Rozważałem też rysowanie mojego konturu wcv::Mat, filtrowanie Maty (za pomocą rozmycia lub operacji morfologicznych) i ponowne znalezienie konturów, ale jest powolne i nieoptymalne. Idealnie więc mógłbym wykonać zadanie, używając wyłącznie sekwencji punktów.

Przeczytałem kilka postów na ten temat i naiwnie pomyślałem, że mogę po prostu przekonwertowaćstd::vector(zcv::Point) do acv::Mat a następnie funkcje OpenCV, takie jak rozmycie / zmiana rozmiaru, wykonają pracę za mnie ... ale nie zrobiły tego.

Oto, co próbowałem:

int main( int argc, char** argv ){

    cv::Mat conv,ori;
    ori=cv::imread(argv[1]);
    ori.copyTo(conv);
    cv::cvtColor(ori,ori,CV_BGR2GRAY);

    std::vector<std::vector<cv::Point> > contours;
    std::vector<cv::Vec4i > hierarchy;

    cv::findContours(ori, contours,hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);

    for(int k=0;k<100;k += 2){
        cv::Mat smoothCont;

        smoothCont = cv::Mat(contours[0]);
        std::cout<<smoothCont.rows<<"\t"<<smoothCont.cols<<std::endl;
        /* Try smoothing: no modification of the array*/
//        cv::GaussianBlur(smoothCont, smoothCont, cv::Size(k+1,1),k);
        /* Try sampling: "Assertion failed (func != 0) in resize"*/
//        cv::resize(smoothCont,smoothCont,cv::Size(0,0),1,1);
        std::vector<std::vector<cv::Point> > v(1);
        smoothCont.copyTo(v[0]);
        cv::drawContours(conv,v,0,cv::Scalar(255,0,0),2,CV_AA);
        std::cout<<k<<std::endl;
        cv::imshow("conv", conv);
        cv::waitKey();
    }
    return 1;
}

Czy ktoś mógłby wyjaśnić, jak to zrobić?

Ponadto, ponieważ prawdopodobnie pracuję ze znacznie mniejszymi konturami, zastanawiałem się, w jaki sposób to podejście poradziłoby sobie z efektem granicznym (np. Podczas wygładzania, ponieważ kontury są okrągłe, ostatnie elementy sekwencji muszą być użyte do obliczenia nowej wartości pierwsze elementy ...)

Dziękuję bardzo za porady,

Edytować:

Próbowałem teżcv::approxPolyDP() ale, jak widzisz, ma tendencję do zachowania ekstremalnych punktów (które chcę usunąć):

Epsilon = 0

Epsilon = 6

Epsilon = 12

Epsilon = 24

Edytuj 2: Jak sugeruje Ben, wydaje się, żecv::GaussianBlur() nie jest obsługiwany, alecv::blur() jest. Wygląda znacznie bliżej moich oczekiwań. Oto moje wyniki, które go używają:

k = 13

k = 53

k = 103

Aby obejść efekt granicy, zrobiłem:

    cv::copyMakeBorder(smoothCont,smoothCont, (k-1)/2,(k-1)/2 ,0, 0, cv::BORDER_WRAP);
    cv::blur(smoothCont, result, cv::Size(1,k),cv::Point(-1,-1));
    result.rowRange(cv::Range((k-1)/2,1+result.rows-(k-1)/2)).copyTo(v[0]);

Nadal szukam rozwiązań interpolujących / próbkujących mój kontur.

questionAnswers(7)

yourAnswerToTheQuestion