Branch points of the skeleton

Viewed 298

My code should find the branch points of the skeleton, but the points it finds are not them. Most likely this is because IMREAD_COLOR = 1, not 0. But if I set the value to 0, then it stops finding and marking points altogether. Is it because the type of points (p1, p2, etc) does not match Mattype or something else? How do I fix this?

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);
}

Incorrect image

1 Answers

There are a few things you should do with your code:

  1. Read the image in using cv::imread("binary_skeleton.jpg", cv::IMREAD_GRAYSCALE). The option you are using forces the image to be RGB, but you are using the image as if if had a single channel.

  2. Instead of comparing if (0 == p1) to find set pixels, use if (128 > p1). JPEG compression could change the value of pixels, so the image will not have only values of 0 and 255, even if those were the values written to file. Some variation around these values will exist. We simply threshold half-way to ensure that any low value is seen as a skeleton pixel. Likewise, replace if (p9 == p1) with if (128 > p9).

  3. Branch points always have more than two neighbors set. When two neighbors are set, it’s a point along a line. Instead of if (same == 2) use if (same > 2).

  4. Remove the second assignment to p1, it has no effect.

Related