スケルトンの分岐点

Sep 17 2020

私のコードはスケルトンの分岐点を見つけるはずですが、見つけた点はそれらではありません。おそらくこれはIMREAD_COLOR、0ではなく= 1であるためです。しかし、値を0に設定すると、ポイントの検索とマーク付けが完全に停止します。ポイントの種類(p1、p2など)が一致しないなどの理由Mattypeでしょうか?これを修正するにはどうすればよいですか?

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

画像が正しくありません

回答

1 CrisLuengo Sep 17 2020 at 13:56

コードで行うべきことがいくつかあります。

  1. を使用して画像を読んでくださいcv::imread("binary_skeleton.jpg", cv::IMREAD_GRAYSCALE)。使用しているオプションは、画像を強制的にRGBにしますが、単一のチャネルがあるかのように画像を使用しています。

  2. 比較if (0 == p1)して設定されたピクセルを見つける代わりに、を使用しますif (128 > p1)。JPEG圧縮はピクセルの値を変更する可能性があるため、ファイルに書き込まれた値であっても、画像の値は0と255だけではありません。これらの値の周りにいくつかの変動が存在します。低い値がスケルトンピクセルとして表示されるように、途中でしきい値を設定するだけです。同様に、交換してくださいif (p9 == p1)とif (128 > p9)。

  3. 分岐点には常に3つ以上の隣接点が設定されています。2つの隣接点が設定されている場合、それは線に沿った点です。if (same == 2)使用する代わりにif (same > 2)。

  4. への2番目の割り当てを削除しp1ます。効果はありません。