Isolate stems and petioles

Hi,
I have isolated the stems and petioles of a plant by semantic segmentation like you can see in red overlap in the following image :

now I want to isolate each branch and their intersection, furthermore I want to obtain the 1-pixel wide skeleton of each branch.
I know it’s difficult.
Any idea ?
Thank you !
Best regards

chatGPT answered me this, it will replace humans ! :

#include <opencv2/opencv.hpp>

int main()
{
    // Charger l'image des branches segmentées
    cv::Mat branches = cv::imread("branches.jpg", cv::IMREAD_GRAYSCALE);

    // Calculer la carte de distance
    cv::Mat dist;
    cv::distanceTransform(branches, dist, cv::DIST_L2, 3);

    // Seuiller la carte de distance pour obtenir les points d'intersection
    cv::Mat intersections;
    cv::threshold(dist, intersections, 0.1 * cv::norm(dist), 255, cv::THRESH_BINARY);

    // Appliquer un flou gaussien pour éliminer les points de bruit
    cv::GaussianBlur(intersections, intersections, cv::Size(5, 5), 0);

    // Trouver les contours des points d'intersection
    std::vector<std::vector<cv::Point>> intersectionContours;
    cv::findContours(intersections, intersectionContours, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE);

    // Dessiner les contours des points d'intersection sur une image noire
    cv::Mat intersectionImage = cv::Mat::zeros(intersections.size(), CV_8UC1);
    cv::drawContours(intersectionImage, intersectionContours, -1, cv::Scalar(255), 2);

    // Trouver les lignes des branches en utilisant la transformée de Hough
    std::vector<cv::Vec4i> lines;
    cv::HoughLinesP(branches, lines, 1, CV_PI / 180, 50, 30, 10);

    // Dessiner les lignes sur une image noire
    cv::Mat linesImage = cv::Mat::zeros(branches.size(), CV_8UC1);
    for (const auto& line : lines)
    {
        cv::line(linesImage, cv::Point(line[0], line[1]), cv::Point(line[2], line[3]), cv::Scalar(255), 2);
    }

    // Dessiner les branches séparées sur une image noire
    cv::Mat separatedImage = cv::Mat::zeros(branches.size(), CV_8UC1);
    for (const auto& line : lines)
    {
        cv::LineIterator it(branches, cv::Point(line[0], line[1]), cv::Point(line[2], line[3]), 8);
        for (int i = 0; i < it.count; ++i, ++it)
        {
            if (intersectionImage.at<uchar>(it.pos()) > 0)
            {
                cv::line(separatedImage, cv::Point(line[0], line[1]), it.pos(), cv::Scalar(255), 1);
                cv::line(separatedImage, cv::Point(line[2], line[3]), it.pos(), cv::Scalar(255), 1);
                break;
            }
            else
            {
                separatedImage.at<uchar>(it.pos()) = 255;
            }
        }
    }

    // Afficher les résultats
    cv::imshow("Branches", branches);
    cv::imshow("Points d'intersection", intersectionImage);
    cv::imshow("Lignes des branches", linesImage);
    cv::imshow("Branches séparées", separatedImage);
    cv::waitKey();

    return 0;
}
1 Like