骨架的分支点
Branch points of the skeleton
我的代码应该找到骨架的分支点,但它找到的点不是它们。这很可能是因为 IMREAD_COLOR
= 1,而不是 0。但是如果我将值设置为 0,那么它会完全停止查找和标记点。是因为点的类型 (p1, p2, etc) 不匹配 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);
}
Incorrect image
您应该对代码执行以下操作:
使用cv::imread("binary_skeleton.jpg", cv::IMREAD_GRAYSCALE)
读取图像。您使用的选项强制图像为 RGB,但您使用的图像就好像只有一个通道一样。
不要比较 if (0 == p1)
来查找设置像素,而是使用 if (128 > p1)
。 JPEG 压缩可能会改变像素值,因此图像不会只有 0 和 255 值,即使这些值已写入文件。将存在围绕这些值的一些变化。我们简单地阈值 half-way 以确保任何低值都被视为骨架像素。同样,将 if (p9 == p1)
替换为 if (128 > p9)
.
分支点总是有两个以上的邻居集。当设置了两个邻居时,它是一条线上的一个点。而不是 if (same == 2)
使用 if (same > 2)
.
去掉对p1
的第二个赋值,没有效果
我的代码应该找到骨架的分支点,但它找到的点不是它们。这很可能是因为 IMREAD_COLOR
= 1,而不是 0。但是如果我将值设置为 0,那么它会完全停止查找和标记点。是因为点的类型 (p1, p2, etc) 不匹配 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);
}
Incorrect image
您应该对代码执行以下操作:
使用
cv::imread("binary_skeleton.jpg", cv::IMREAD_GRAYSCALE)
读取图像。您使用的选项强制图像为 RGB,但您使用的图像就好像只有一个通道一样。不要比较
if (0 == p1)
来查找设置像素,而是使用if (128 > p1)
。 JPEG 压缩可能会改变像素值,因此图像不会只有 0 和 255 值,即使这些值已写入文件。将存在围绕这些值的一些变化。我们简单地阈值 half-way 以确保任何低值都被视为骨架像素。同样,将if (p9 == p1)
替换为if (128 > p9)
.分支点总是有两个以上的邻居集。当设置了两个邻居时,它是一条线上的一个点。而不是
if (same == 2)
使用if (same > 2)
.去掉对
p1
的第二个赋值,没有效果