Ask Your Question

Revision history [back]

@pedro Batista is good. I propose this method. Shape mustn't have hole before processing : opening and closing are necessary.

    Mat imOriginal = imread("test.png", IMREAD_GRAYSCALE);
    Mat imOri = imOriginal > 1;
    Mat img = imOri.clone();
    Mat kernel;
    kernel=getStructuringElement(CV_SHAPE_CROSS, Size(3, 3));

    int nbC = 2;
    int nbIter = 0;
    Mat dst,labels;
    Mat prevErode;
    while (nbC == 2)
    {
        erode(img, dst, kernel);
        nbC = connectedComponents(dst, labels);
        nbIter++;
        if (nbC == 2)
        {
            prevErode = img.clone();
            img = dst;
        }
        imshow("erode", dst);
        waitKey(0);
    }
    Mat shape1 = labels == 1,dst1;
    Mat shape2 = labels == 2,dst2;
    Mat inter(imOri.size(), CV_8UC1, Scalar(0));
    for (int i = 0;i <= nbIter; i++)
    {
        dilate(shape1, dst1, kernel);
        dilate(shape2, dst2, kernel);
        add(inter, Scalar(1), inter, dst1&dst2);
        shape1 = dst1;
        shape2 = dst2;
    }

    imshow("Boundaries", inter>0);
    cvtColor(imOri, imOri, CV_GRAY2BGR);
    imOri.setTo(Scalar(0, 255, 0), inter > 0);
    imshow("Split shape",imOri);
    waitKey(0);
    imwrite("bilan.png",imOri);

Result is image description

@pedro Batista is good. I propose this method. method (and need to be tested). Shape mustn't have hole before processing : opening and closing are necessary.

    Mat imOriginal = imread("test.png", IMREAD_GRAYSCALE);
    Mat imOri = imOriginal > 1;
    Mat img = imOri.clone();
    Mat kernel;
    kernel=getStructuringElement(CV_SHAPE_CROSS, Size(3, 3));

    int nbC = 2;
    int nbIter = 0;
    Mat dst,labels;
    Mat prevErode;
    while (nbC == 2)
    {
        erode(img, dst, kernel);
        nbC = connectedComponents(dst, labels);
        nbIter++;
        if (nbC == 2)
        {
            prevErode = img.clone();
            img = dst;
        }
        imshow("erode", dst);
        waitKey(0);
    }
    Mat shape1 = labels == 1,dst1;
    Mat shape2 = labels == 2,dst2;
    Mat inter(imOri.size(), CV_8UC1, Scalar(0));
    for (int i = 0;i <= nbIter; i++)
    {
        dilate(shape1, dst1, kernel);
        dilate(shape2, dst2, kernel);
        add(inter, Scalar(1), inter, dst1&dst2);
        shape1 = dst1;
        shape2 = dst2;
    }

    imshow("Boundaries", inter>0);
    cvtColor(imOri, imOri, CV_GRAY2BGR);
    imOri.setTo(Scalar(0, 255, 0), inter > 0);
    imshow("Split shape",imOri);
    waitKey(0);
    imwrite("bilan.png",imOri);

Result is image description

@pedro Batista is good. post incude many good idea to solve this problem too. I propose this method (and need to be tested). Shape mustn't have hole before processing : opening and closing are necessary.

    Mat imOriginal = imread("test.png", IMREAD_GRAYSCALE);
    Mat imOri = imOriginal > 1;
    Mat img = imOri.clone();
    Mat kernel;
    kernel=getStructuringElement(CV_SHAPE_CROSS, Size(3, 3));

    int nbC = 2;
    int nbIter = 0;
    Mat dst,labels;
    Mat prevErode;
    while (nbC == 2)
    {
        erode(img, dst, kernel);
        nbC = connectedComponents(dst, labels);
        nbIter++;
        if (nbC == 2)
        {
            prevErode = img.clone();
            img = dst;
        }
        imshow("erode", dst);
        waitKey(0);
    }
    Mat shape1 = labels == 1,dst1;
    Mat shape2 = labels == 2,dst2;
    Mat inter(imOri.size(), CV_8UC1, Scalar(0));
    for (int i = 0;i <= nbIter; i++)
    {
        dilate(shape1, dst1, kernel);
        dilate(shape2, dst2, kernel);
        add(inter, Scalar(1), inter, dst1&dst2);
        shape1 = dst1;
        shape2 = dst2;
    }

    imshow("Boundaries", inter>0);
    cvtColor(imOri, imOri, CV_GRAY2BGR);
    imOri.setTo(Scalar(0, 255, 0), inter > 0);
    imshow("Split shape",imOri);
    waitKey(0);
    imwrite("bilan.png",imOri);

Result is image description