Opencv学习笔记DNN模块的blobFromImage函数、forward函
官⽹以及⽹上对blobFromImage函数、forward函数讲解的很详细,但是对于输出的结果⼏乎没有介绍,所以很多时候再对于输出之后怎么处理让⼈⽐较困惑。
blobFromImage函数原型
blobFromImage(InputArray image,
double scalefactor=1.0,
const Size& size = Size(),
const Scalar& mean = Scalar(),
bool swapRB = false,
bool crop = false,
int ddepth = CV_32F)
image:这个就是我们将要输⼊神经⽹络进⾏处理或者分类的图⽚。
mean:需要将图⽚整体减去的平均值,如果我们需要对RGB图⽚的三个通道分别减去不同的值,那么可以使⽤3组平均值,如果只使⽤⼀组,那么就默认对三个通道减去⼀样的值。减去平均值(mean):为了消除同⼀场景下不同光照的图⽚,对我们最终的分类或者神经⽹络的影响,我们常常对图⽚的R、G、B通道的像素求⼀个平均值,然后将每个像素值减去我们的平均值,这样就可以得到像素之间的相对值,就可以排除光照的影响。
scalefactor:当我们将图⽚减去平均值之后,还可以对剩下的像素值进⾏⼀定的尺度缩放,它的默认值是1,如果希望减去平均像素之后的值,全部缩⼩⼀半,那么可以将scalefactor设为1/2。
size:这个参数是我们神经⽹络在训练的时候要求输⼊的图⽚尺⼨。
swapRB:OpenCV中认为我们的图⽚通道顺序是BGR,但是我平均值假设的顺序是RGB,所以如果需要交换R和G,那么就要使
swapRB=true
函数内的参数需要根据你训练的⽹络的相关参数调整。
blobFromImage函数输出
函数返回4D矩阵(没有定义⾏/列值,因此这些值为-1)。
Mat [ -1*-1*CV_32FC1, isCont=true, isSubmat=false, nativeObj=0xaa2fd0, dataAddr=0x18d93080 ]
对于返回值有疑问,参见opencv官⽅issues
forward函数原型
Mat cv::dnn::Net::forward(const String & outputName = String())
这个函数只需要提供layer的name即可;函数返回⼀个Mat变量,返回值是指输⼊的layername⾸次出现的输出。默认输出整个⽹络的运⾏结果。
还有其它三个重载,请参考:
对于返回结果的处理的参考代码1 - ⽬标识别:
Mat blob = blobFromImage(image, 1, Size(), Scalar(104, 117, 123));
net.setInput(blob);
Mat detections = net.forward();
Mat detectionMat(detections.size[2], detections.size[3], CV_32F, detections.ptr<float>());
for (int i = 0; i < ws; i++)
{
//⾃定义阈值
if (detectionMat.at<float>(i, 2) >= 0.14)
{
int xLeftBottom = static_cast<int>(detectionMat.at<float>(i, 3) * ls);
int yLeftBottom = static_cast<int>(detectionMat.at<float>(i, 4) * ws);
int xRightTop = static_cast<int>(detectionMat.at<float>(i, 5) * ls);
int yRightTop = static_cast<int>(detectionMat.at<float>(i, 6) * ws);
Rect object((int)xLeftBottom, (int)yLeftBottom,
(int)(xRightTop - xLeftBottom),
(int)(yRightTop - yLeftBottom));
rectangle(image, object, Scalar(0, 255, 0));
}
}
对于返回结果的处理的参考代码2 - 语义分割:
Mat blob = OpenCvSharp.Dnn.CvDnn.BlobFromImage(frame, 1.0 / 255, new OpenCvSharp.Size(256, 256), new Scalar(), false, false); net.SetInput(blob);
Stopwatch sw = new Stopwatch();
sw.Start();
Mat prob = net.Forward(/*outNames[0]*/);
sw.Stop();
Console.WriteLine($"Runtime:{sw.ElapsedMilliseconds} ms");
Mat p = prob.Reshape(1, prob.Size(2));
Mat res = new Mat(p.Size(), MatType.CV_8UC1, Scalar.All(255));
for(int h=0; h<p.Height; h++)
{
for (int w = 0; w < p.Width; w++)
{
res.Set<byte>(h, w, (byte)(p.At<float>(h, w) * 100));
}
}
对于返回结果的处理的参考代码3 - ⽬标分类1:
int main(int argc, char** argv)
{
Net net = readNetFromCaffe("C:/Users/xiaomao/Desktop/dnn/bvlc_googlenet.prototxt", "C:/Users/xiaomao/Desktop/dnn/bvlc_googlenet.caffemodel"); Mat image = imread("C:/Users/xiaomao/Desktop/8.png");
Mat inputBlob = blobFromImage(image, 1, Size(224, 224), Scalar(104, 117, 123));
Mat prob;
cv::TickMeter t;
for (int i = 0; i < 10; i++)
{
CV_TRACE_REGION("forward");
net.setInput(inputBlob, "data");        //set the network input
t.start();
prob = net.forward("prob");                          //compute output
t.stop();
}
int classId;
double classProb;
getMaxClass(prob, &classId, &classProb);//find the best class
std::vector<String> classNames = readClassNames();
string text = classNames.at(classId) + to_string(classProb * 100);
putText(image, text, Point(5, 25), FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2);
std::cout << "Best class: #" << classId << " '" << classNames.at(classId) << "'" << std::endl;
std::cout << "Probability: " << classProb * 100 << "%" << std::endl;
std::cout << "Time: " << (TimeMilli() / t.getCounter() << " ms (average from " << t.getCounter() << " iterations)" << std::endl;
imshow("Image", image);
waitKey(0);
//system("pause");
writeline函数
return 0;
}
对于返回结果的处理的参考代码3 - ⽬标分类2:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。