Search code examples
opencvimage-segmentationcontour

Contour segmentation


I have a contour which consists of curved segments and straigth segments. Is there any possibility to segment the contour into the curved and straigth parts? So this is an example for a contour

original image

I would like to have a segmentation like this:

segmented image

Do you have any idea how I could solve such a problem

Thank you very much and best regards


Solution

  • Yes I got the solution with the link @PSchn posted. I just go through the contour points and defined a border. Everything under the border is a "curved segment" everthing else is a straigth segment. Thank you for your help!!

    vector<double> getCurvature(vector<Point> const& tContourPoints, int tStepSize)
    {
    int iplus;
    int iminus;
    
    double acurvature;
    double adivisor;
    
    Point2f pplus;
    Point2f pminus;
    // erste Ableitung
    Point2f a1stDerivative;
    // zweite Ableitung
    Point2f a2ndDerivative;
    
    vector< double > rVecCurvature( tContourPoints.size() );
    
    if ((int)tContourPoints.size() < tStepSize)
    {
        return rVecCurvature;
    }
    
    for (int i = 0; i < (int)tContourPoints.size(); i++ )
    {
        const Point2f& pos = tContourPoints[i];
    
        iminus  = i-tStepSize;
        iplus   = i+tStepSize;
    
        if(iminus < 0)
        {
            pminus = tContourPoints[iminus + tContourPoints.size()];
        }
        else
        {
            pminus = tContourPoints[iminus];
        }
    
        if(iplus  > (int)tContourPoints.size())
        {
            pplus = tContourPoints[iplus - (int)tContourPoints.size()];
        }
        else
        {
            pplus = tContourPoints[iplus];
        }
    
        a1stDerivative.x = (pplus.x -           pminus.x) / ( iplus-iminus);
        a1stDerivative.y = (pplus.y -           pminus.y) / ( iplus-iminus);
        a2ndDerivative.x = (pplus.x - 2*pos.x + pminus.x) / ((iplus-iminus)/2*(iplus-iminus)/2);
        a2ndDerivative.y = (pplus.y - 2*pos.y + pminus.y) / ((iplus-iminus)/2*(iplus-iminus)/2);
    
    
        adivisor = a2ndDerivative.x*a2ndDerivative.x + a2ndDerivative.y*a2ndDerivative.y;
        if (  abs(adivisor) > 10e-8 )
        {
            acurvature =   abs(a2ndDerivative.y*a1stDerivative.x - a2ndDerivative.x*a1stDerivative.y) / pow(adivisor, 3.0/2.0 )  ;
        }
        else
        {
            acurvature =  numeric_limits<double>::infinity();
        }
    
        rVecCurvature[i] = acurvature;
    }
    return rVecCurvature;
    }
    

    Once I get the curvature I defined a border and went through my contour:

    acurvature = getCurvature(aContours_img[0], 50);
    
    if(acurvature.size() > 0)
    {
        // aSegmentChange =1 --> curved segment
       // aSegmentChange =0 --> straigth segment
        if( acurvature[0] < aBorder)
        {
            aSegmentChange = 1;
        }
        else
        {
            aSegmentChange = 0;
        }
    
        // Kontur segmentieren
        for(int i = 0; i < (int)acurvature.size(); i++)
        {
            aSegments[aSegmentIndex].push_back(aContours_img[0][i]);
            aCurveIndex[aSegmentIndex].push_back(aSegmentChange);
    
            if( acurvature[i] < aBorder && aSegmentChange == 0 )
            {
                aSegmentIndex++;
                aSegmentChange = 1;
            }
            if( acurvature[i] > aBorder && aSegmentChange == 1 )
            {
                aSegmentIndex++;
                aSegmentChange = 0;
            }
    
            if(aSegmentIndex >= (int)aSegments.size()-1)
            {
                aSegments.resize(aSegmentIndex+1);
                aCurveIndex.resize(aSegmentIndex+1);
            }
        }
    }