Points de branche du squelette

Sep 17 2020

Mon code devrait trouver les points de branchement du squelette, mais les points qu'il trouve ne sont pas eux. C'est probablement parce que IMREAD_COLOR= 1, pas 0. Mais si je mets la valeur à 0, alors il arrête de trouver et de marquer des points complètement. Est-ce parce que le type de points (p1, p2, etc.) ne correspond pas Mattypeou autre chose? Comment puis-je réparer ça?

int main() {
    cv::Mat thresh = cv::imread("binary_skeleton.jpg", 1);
    if (thresh.empty())
        return -1;

    for (int i = 1; i < thresh.rows - 1; i++)
    {
        for (int j = 1; j < thresh.cols - 1; j++)
        {
            uchar p1 = thresh.at<uchar>(i, j);
            if (0 == p1)
            {
                uchar p1 = thresh.at<uchar>(i, j);
                uchar p2 = thresh.at<uchar>(i - 1, j);
                uchar p3 = thresh.at<uchar>(i - 1, j + 1);
                uchar p4 = thresh.at<uchar>(i, j + 1);
                uchar p5 = thresh.at<uchar>(i + 1, j + 1);
                uchar p6 = thresh.at<uchar>(i + 1, j);
                uchar p7 = thresh.at<uchar>(i + 1, j - 1);
                uchar p8 = thresh.at<uchar>(i, j - 1);
                uchar p9 = thresh.at<uchar>(i - 1, j - 1);

                int same = 0;
                if (p9 == p1) { ++same; }
                if (p8 == p1) { ++same; }
                if (p7 == p1) { ++same; }
                if (p6 == p1) { ++same; }
                if (p5 == p1) { ++same; }
                if (p4 == p1) { ++same; }
                if (p3 == p1) { ++same; }
                if (p2 == p1) { ++same; }

                if (same == 2)
                {
                    circle(thresh, Point(j, i), 3, Scalar(255, 120, 0), 1);
                }
            }
        }
    }
    cv::imshow("", thresh);
    cv::waitKey(0);
}

Image incorrecte

Réponses

1 CrisLuengo Sep 17 2020 at 13:56

Il y a quelques choses que vous devriez faire avec votre code:

  1. Lisez l'image en utilisant cv::imread("binary_skeleton.jpg", cv::IMREAD_GRAYSCALE). L'option que vous utilisez force l'image à être RVB, mais vous utilisez l'image comme si elle avait un seul canal.

  2. Au lieu de comparer if (0 == p1)pour trouver les pixels définis, utilisez if (128 > p1). La compression JPEG peut modifier la valeur des pixels, de sorte que l'image n'aura pas que des valeurs de 0 et 255, même s'il s'agissait des valeurs écrites dans le fichier. Une certaine variation autour de ces valeurs existera. Nous limitons simplement à mi-chemin pour nous assurer que toute valeur faible est considérée comme un pixel squelette. De même, remplacez if (p9 == p1)par if (128 > p9).

  3. Les points de branchement ont toujours plus de deux voisins définis. Lorsque deux voisins sont définis, c'est un point le long d'une ligne. Au lieu de l' if (same == 2)utiliser if (same > 2).

  4. Supprimez la deuxième affectation à p1, cela n'a aucun effet.