如何使用 EmguCV 检测自定义对象
How to detect custom object using EmguCV
我正在编写一些对象检测代码。所以,我进行了培训,并从 tensorflow 获得了 .pb 和 graph.pbtxt 文件。我做的下一件事是 python 代码,它基于这两个文件执行我的对象检测,使用 opencv for Python。
这是我的 python 脚本,效果很好:
import cv2 as cv
cvNet = cv.dnn.readNetFromTensorflow('frozen_inference_graph.pb', 'graph.pbtxt')
img = cv.imread('75.png')
rows = img.shape[0]
cols = img.shape[1]
cvNet.setInput(cv.dnn.blobFromImage(img, size=(300, 300), swapRB=True, crop=False))
cvOut = cvNet.forward()
print(rows)
print(cols)
for detection in cvOut[0,0,:,:]:
print(type(cvOut[0,0,:,:]))
score = float(detection[2])
if score > 0.1:
left = detection[3] * cols
top = detection[4] * rows
right = detection[5] * cols
bottom = detection[6] * rows
cv.rectangle(img, (int(left), int(top)), (int(right), int(bottom)), (0, 0, 255), thickness=2)
print('true')
print(score)
cv.imshow('img', cv.resize(img, None, fx=0.3, fy=0.3))
cv.waitKey()
但是,我需要使用 .NET (C#) 完成的相同代码,使用 EmguCV 库,它是传统 OpenCV 的包装器。
这是我设法编写的部分代码:
private bool RecognizeCO(string fileName)
{
Image<Bgr, byte> img = new Image<Bgr, byte>(fileName);
int cols = img.Width;
int rows = img.Height;
imageBox2.Image = img;
Net netcfg = DnnInvoke.ReadNetFromTensorflow("CO.pb", "graph.pbtxt");
netcfg.SetInput(DnnInvoke.BlobFromImage(img));
Mat mat = netcfg.Forward();
return false;
}
不幸的是,我不知道在那之后要做什么....实际上,我在这段 C# 代码中需要相同的结果,就像在 Python 代码中一样。我知道,我只能从 C# 调用 python 脚本,但我确实需要使用 EmguCV 在 C# 中完成此代码。
请帮我!
预先感谢您的帮助!
所以,我终于设法完成了该代码...
解决方案很简单:
在得到 mat
变量后,我们可以从 Mat
中得到 Data
作为一个 float[] 数组:float[,,,] flt = (float[,,,])mat.GetData();
或者只使用一维数组:float[] flt = (float[])mat.GetData(jagged:false)
(但我更喜欢前一个)
然后,只需循环抛出该数组即可:
for (int x = 0; x < flt.GetLength(2); x++)
{
if (flt[0, 0, x, 2] > 0.1)
{
int left = Convert.ToInt32(flt[0, 0, x, 3] * cols);
int top = Convert.ToInt32(flt[0, 0, x, 4] * rows);
int right = Convert.ToInt32(flt[0, 0, x, 5] * cols);
int bottom = Convert.ToInt32(flt[0, 0, x, 6] * rows);
image1.Draw(new Rectangle(left, top, right - left, bottom - top), new Bgr(0, 0, 255), 2);
}
}
最后,我们可以保存该图像:
image1.Save("testing-1.png");
因此,结果代码如下所示:
using (Image<Bgr, byte> image1 = new Image<Bgr, byte>("testing.png"))
{
int interception = 0;
int cols = image1.Width;
int rows = image1.Height;
Net netcfg = DnnInvoke.ReadNetFromTensorflow(Directory.GetCurrentDirectory() + @"\fldr\CO.pb", Directory.GetCurrentDirectory() + @"\fldr\graph.pbtxt");
netcfg.SetInput(DnnInvoke.BlobFromImage(image1.Mat, 1, new System.Drawing.Size(300, 300), default(MCvScalar), true, false));
Mat mat = netcfg.Forward();
float[,,,] flt = (float[,,,])mat.GetData();
for (int x = 0; x < flt.GetLength(2); x++)
{
if (flt[0, 0, x, 2] > 0.1)
{
int left = Convert.ToInt32(flt[0, 0, x, 3] * cols);
int top = Convert.ToInt32(flt[0, 0, x, 4] * rows);
int right = Convert.ToInt32(flt[0, 0, x, 5] * cols);
int bottom = Convert.ToInt32(flt[0, 0, x, 6] * rows);
image1.Draw(new Rectangle(left, top, right - left, bottom - top), new Bgr(0, 0, 255), 2);
}
}
image1.Save("testing-1.png");
}
我正在编写一些对象检测代码。所以,我进行了培训,并从 tensorflow 获得了 .pb 和 graph.pbtxt 文件。我做的下一件事是 python 代码,它基于这两个文件执行我的对象检测,使用 opencv for Python。 这是我的 python 脚本,效果很好:
import cv2 as cv
cvNet = cv.dnn.readNetFromTensorflow('frozen_inference_graph.pb', 'graph.pbtxt')
img = cv.imread('75.png')
rows = img.shape[0]
cols = img.shape[1]
cvNet.setInput(cv.dnn.blobFromImage(img, size=(300, 300), swapRB=True, crop=False))
cvOut = cvNet.forward()
print(rows)
print(cols)
for detection in cvOut[0,0,:,:]:
print(type(cvOut[0,0,:,:]))
score = float(detection[2])
if score > 0.1:
left = detection[3] * cols
top = detection[4] * rows
right = detection[5] * cols
bottom = detection[6] * rows
cv.rectangle(img, (int(left), int(top)), (int(right), int(bottom)), (0, 0, 255), thickness=2)
print('true')
print(score)
cv.imshow('img', cv.resize(img, None, fx=0.3, fy=0.3))
cv.waitKey()
但是,我需要使用 .NET (C#) 完成的相同代码,使用 EmguCV 库,它是传统 OpenCV 的包装器。
这是我设法编写的部分代码:
private bool RecognizeCO(string fileName)
{
Image<Bgr, byte> img = new Image<Bgr, byte>(fileName);
int cols = img.Width;
int rows = img.Height;
imageBox2.Image = img;
Net netcfg = DnnInvoke.ReadNetFromTensorflow("CO.pb", "graph.pbtxt");
netcfg.SetInput(DnnInvoke.BlobFromImage(img));
Mat mat = netcfg.Forward();
return false;
}
不幸的是,我不知道在那之后要做什么....实际上,我在这段 C# 代码中需要相同的结果,就像在 Python 代码中一样。我知道,我只能从 C# 调用 python 脚本,但我确实需要使用 EmguCV 在 C# 中完成此代码。 请帮我! 预先感谢您的帮助!
所以,我终于设法完成了该代码...
解决方案很简单:
在得到 mat
变量后,我们可以从 Mat
中得到 Data
作为一个 float[] 数组:float[,,,] flt = (float[,,,])mat.GetData();
或者只使用一维数组:float[] flt = (float[])mat.GetData(jagged:false)
(但我更喜欢前一个)
然后,只需循环抛出该数组即可:
for (int x = 0; x < flt.GetLength(2); x++)
{
if (flt[0, 0, x, 2] > 0.1)
{
int left = Convert.ToInt32(flt[0, 0, x, 3] * cols);
int top = Convert.ToInt32(flt[0, 0, x, 4] * rows);
int right = Convert.ToInt32(flt[0, 0, x, 5] * cols);
int bottom = Convert.ToInt32(flt[0, 0, x, 6] * rows);
image1.Draw(new Rectangle(left, top, right - left, bottom - top), new Bgr(0, 0, 255), 2);
}
}
最后,我们可以保存该图像:
image1.Save("testing-1.png");
因此,结果代码如下所示:
using (Image<Bgr, byte> image1 = new Image<Bgr, byte>("testing.png"))
{
int interception = 0;
int cols = image1.Width;
int rows = image1.Height;
Net netcfg = DnnInvoke.ReadNetFromTensorflow(Directory.GetCurrentDirectory() + @"\fldr\CO.pb", Directory.GetCurrentDirectory() + @"\fldr\graph.pbtxt");
netcfg.SetInput(DnnInvoke.BlobFromImage(image1.Mat, 1, new System.Drawing.Size(300, 300), default(MCvScalar), true, false));
Mat mat = netcfg.Forward();
float[,,,] flt = (float[,,,])mat.GetData();
for (int x = 0; x < flt.GetLength(2); x++)
{
if (flt[0, 0, x, 2] > 0.1)
{
int left = Convert.ToInt32(flt[0, 0, x, 3] * cols);
int top = Convert.ToInt32(flt[0, 0, x, 4] * rows);
int right = Convert.ToInt32(flt[0, 0, x, 5] * cols);
int bottom = Convert.ToInt32(flt[0, 0, x, 6] * rows);
image1.Draw(new Rectangle(left, top, right - left, bottom - top), new Bgr(0, 0, 255), 2);
}
}
image1.Save("testing-1.png");
}