Emgu CV - EmguCV 中图像的骨架(骨架化)
Emgu CV - Skeleton of an Image in EmguCV (Skeletonization)
我需要在 Emgu CV 中实现骨架化,但我没有成功。
我在下面的网站上提到了一个代码,但它不起作用:
Skeletonization using EmguCV^]
以下代码无效:
Image<Gray, Byte> eroded = new Image<Gray, byte>(img2.Size);
Image<Gray, Byte> temp = new Image<Gray, byte>(img2.Size);
Image<Gray, Byte> skel = new Image<Gray, byte>(img2.Size);
skel.SetValue(0);
CvInvoke.cvThreshold(img2, img2, 127, 256, 0);
StructuringElementEx element = new StructuringElementEx(3, 3, 1, 1, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_CROSS);
bool done = false;
while (!done)
{
CvInvoke.cvErode(img2, eroded, element,1);
CvInvoke.cvDilate(eroded, temp, element,1);
temp = img2.Sub(temp);
skel = skel | temp;
img2 = eroded;
if (CvInvoke.cvCountNonZero(img2) == 0) done = true;
}
此代码有效,但在视频(连续帧)中速度非常慢
Image<Gray, byte> Skeleton(Image<Gray, byte> orgImg)
{
Image<Gray, byte> skel = new Image<Gray, byte>(orgImg.Size);
for (int y = 0; y < skel.Height; y++)
for (int x = 0; x < skel.Width; x++)
skel.Data[y, x, 0] = 0;
imageBoxOutputROI.Image = skel;
Image<Gray, byte> img = skel.Copy();
for (int y = 0; y < skel.Height; y++)
for (int x = 0; x < skel.Width; x++)
img.Data[y, x, 0] = orgImg.Data[y, x, 0];
StructuringElementEx element;
element = new StructuringElementEx(3, 3, 1, 1, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_CROSS);
Image<Gray, byte> temp;
bool done = false;
do
{
temp = img.MorphologyEx(element, Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_OPEN, 1);
temp = temp.Not();
temp = temp.And(img);
skel = skel.Or(temp);
img = img.Erode(1);
double[] min, max;
Point[] pmin, pmax;
img.MinMax(out min, out max, out pmin, out pmax);
done = (max[0] == 0);
} while (!done);
return skel;
}
输入图像:
我需要帮助来实现骨架化代码。
在以下网站进行了研究,但我没有成功:
http://felix.abecassis.me/2011/09/opencv-morphological-skeleton/[^]
^]
^]
非常感谢您的帮助。
理查德·J·阿尔加维
试试下面的代码。
它适用于我(我的输入图像有白色背景)。我认为您的代码的问题是 Sub
和 Or
运算符。
public static Bitmap Skelatanize(Bitmap image)
{
Image<Gray, byte> imgOld = new Image<Gray, byte>(image);
Image<Gray, byte> img2 = (new Image<Gray, byte>(imgOld.Width, imgOld.Height, new Gray(255))).Sub(imgOld);
Image<Gray, byte> eroded = new Image<Gray, byte>(img2.Size);
Image<Gray, byte> temp = new Image<Gray, byte>(img2.Size);
Image<Gray, byte> skel = new Image<Gray, byte>(img2.Size);
skel.SetValue(0);
CvInvoke.Threshold(img2, img2, 127, 256, 0);
var element = CvInvoke.GetStructuringElement(ElementShape.Cross, new Size(3, 3), new Point(-1, -1));
bool done = false;
while (!done)
{
CvInvoke.Erode(img2, eroded, element, new Point(-1, -1), 1, BorderType.Reflect, default(MCvScalar));
CvInvoke.Dilate(eroded, temp, element, new Point(-1, -1), 1, BorderType.Reflect, default(MCvScalar));
CvInvoke.Subtract(img2, temp, temp);
CvInvoke.BitwiseOr(skel, temp, skel);
eroded.CopyTo(img2);
if (CvInvoke.CountNonZero(img2) == 0) done = true;
}
return skel.Bitmap;
}
我需要在 Emgu CV 中实现骨架化,但我没有成功。 我在下面的网站上提到了一个代码,但它不起作用: Skeletonization using EmguCV^]
以下代码无效:
Image<Gray, Byte> eroded = new Image<Gray, byte>(img2.Size);
Image<Gray, Byte> temp = new Image<Gray, byte>(img2.Size);
Image<Gray, Byte> skel = new Image<Gray, byte>(img2.Size);
skel.SetValue(0);
CvInvoke.cvThreshold(img2, img2, 127, 256, 0);
StructuringElementEx element = new StructuringElementEx(3, 3, 1, 1, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_CROSS);
bool done = false;
while (!done)
{
CvInvoke.cvErode(img2, eroded, element,1);
CvInvoke.cvDilate(eroded, temp, element,1);
temp = img2.Sub(temp);
skel = skel | temp;
img2 = eroded;
if (CvInvoke.cvCountNonZero(img2) == 0) done = true;
}
此代码有效,但在视频(连续帧)中速度非常慢
Image<Gray, byte> Skeleton(Image<Gray, byte> orgImg)
{
Image<Gray, byte> skel = new Image<Gray, byte>(orgImg.Size);
for (int y = 0; y < skel.Height; y++)
for (int x = 0; x < skel.Width; x++)
skel.Data[y, x, 0] = 0;
imageBoxOutputROI.Image = skel;
Image<Gray, byte> img = skel.Copy();
for (int y = 0; y < skel.Height; y++)
for (int x = 0; x < skel.Width; x++)
img.Data[y, x, 0] = orgImg.Data[y, x, 0];
StructuringElementEx element;
element = new StructuringElementEx(3, 3, 1, 1, Emgu.CV.CvEnum.CV_ELEMENT_SHAPE.CV_SHAPE_CROSS);
Image<Gray, byte> temp;
bool done = false;
do
{
temp = img.MorphologyEx(element, Emgu.CV.CvEnum.CV_MORPH_OP.CV_MOP_OPEN, 1);
temp = temp.Not();
temp = temp.And(img);
skel = skel.Or(temp);
img = img.Erode(1);
double[] min, max;
Point[] pmin, pmax;
img.MinMax(out min, out max, out pmin, out pmax);
done = (max[0] == 0);
} while (!done);
return skel;
}
输入图像:
我需要帮助来实现骨架化代码。
在以下网站进行了研究,但我没有成功: http://felix.abecassis.me/2011/09/opencv-morphological-skeleton/[^]
^]
^]
非常感谢您的帮助。
理查德·J·阿尔加维
试试下面的代码。
它适用于我(我的输入图像有白色背景)。我认为您的代码的问题是 Sub
和 Or
运算符。
public static Bitmap Skelatanize(Bitmap image)
{
Image<Gray, byte> imgOld = new Image<Gray, byte>(image);
Image<Gray, byte> img2 = (new Image<Gray, byte>(imgOld.Width, imgOld.Height, new Gray(255))).Sub(imgOld);
Image<Gray, byte> eroded = new Image<Gray, byte>(img2.Size);
Image<Gray, byte> temp = new Image<Gray, byte>(img2.Size);
Image<Gray, byte> skel = new Image<Gray, byte>(img2.Size);
skel.SetValue(0);
CvInvoke.Threshold(img2, img2, 127, 256, 0);
var element = CvInvoke.GetStructuringElement(ElementShape.Cross, new Size(3, 3), new Point(-1, -1));
bool done = false;
while (!done)
{
CvInvoke.Erode(img2, eroded, element, new Point(-1, -1), 1, BorderType.Reflect, default(MCvScalar));
CvInvoke.Dilate(eroded, temp, element, new Point(-1, -1), 1, BorderType.Reflect, default(MCvScalar));
CvInvoke.Subtract(img2, temp, temp);
CvInvoke.BitwiseOr(skel, temp, skel);
eroded.CopyTo(img2);
if (CvInvoke.CountNonZero(img2) == 0) done = true;
}
return skel.Bitmap;
}