OpenCV中blobFromImage函数详细解释

这篇具有很好参考价值的文章主要介绍了OpenCV中blobFromImage函数详细解释。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

OpenCV中blobFromImage函数详细解释

OpenCV 3.3之后的版本中,支持调用训练好的深度学习框架,其中有一些重要的函数,今天先总结一下blobFromImage函数的用法。

在进行深度学习或者图片分类时,blobFromImage主要是用来对图片进行预处理。包含两个主要过程:

整体像素值减去平均值**(mean)**
通过缩放系数**(scalefactor)**对图片像素值进行缩放
下面我们看一下这个函数的形式:

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)

下面我对这些参数,给大家提供给一个简单的介绍:

blob = cv2.dnn.blobFromImage(image, scalefactor=1.0, size, mean, swapRB=True,crop=False,ddepth = CV_32F )

**image:**这个就是我们将要输入神经网络进行处理或者分类的图片。

mean:需要将图片整体减去的平均值,如果我们需要对RGB图片的三个通道分别减去不同的值,那么可以使用3组平均值,如果只使用一组,那么就默认对三个通道减去一样的值。减去平均值**(mean):为了消除同一场景下不同光照的图片,对我们最终的分类或者神经网络的影响,我们常常对图片的R、G、B**通道的像素求一个平均值,然后将每个像素值减去我们的平均值,这样就可以得到像素之间的相对值,就可以排除光照的影响。

scalefactor:当我们将图片减去平均值之后,还可以对剩下的像素值进行一定的尺度缩放,它的默认值是1,如果希望减去平均像素之后的值,全部缩小一半,那么可以将scalefactor设为1/2

**size:**这个参数是我们神经网络在训练的时候要求输入的图片尺寸。

swapRB:OpenCV中认为我们的图片通道顺序是BGR,但是我平均值假设的顺序是RGB,所以如果需要交换RG,那么就要使swapRB=true
crop,如果crop裁剪为真,则调整输入图像的大小,使调整大小后的一侧等于相应的尺寸,另一侧等于或大于。然后,从中心进行裁剪。如果“裁剪”为“假”,则直接调整大小而不进行裁剪并保留纵横比。

ddepth, 输出blob的深度,选则CV_32F or CV_8U。

cv2.dnn.blobFromImage函数返回的blob是我们输入图像进行随意从中心裁剪,减均值、缩放和通道交换的结果。cv2.dnn.blobFromImagescv2.dnn.blobFromImage不同在于,前者接受多张图像,后者接受一张图像。多张图像使用cv2.dnn.blobFromImages有更少的函数调用开销,你将能够更快批处理图像或帧。

2、blobFromImage函数输出
函数返回4D矩阵(没有定义行/列值,因此这些值为-1)。

Mat [ -1*-1*CV_32FC1, isCont=true, isSubmat=false, nativeObj=0xaa2fd0, dataAddr=0x18d93080 ]
对于返回值有疑问,参见opencv官方issues
https://github.com/opencv/opencv/issues/12520
https://github.com/opencv/opencv/issues/12520

3、forward函数原型
Mat cv::dnn::Net::forward(const String & outputName = String())

    这个函数只需要提供layer的name即可;函数返回一个Mat变量,返回值是指输入的layername首次出现的输出。默认输出整个网络的运行结果。

    还有其它三个重载,请参考:

OpenCV4.xDNN(一)_爱CV-CSDN博客
https://blog.csdn.net/qq_35054151/article/details/112487829
https://blog.csdn.net/WHU_Kevin_Lin/article/details/108953227
https://blog.csdn.net/WHU_Kevin_Lin/article/details/108953227

4、对于返回结果的处理

(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 < detectionMat.rows; i++)
{
    //自定义阈值
    if (detectionMat.at<float>(i, 2) >= 0.14)
    {
        int xLeftBottom = static_cast<int>(detectionMat.at<float>(i, 3) * image.cols);
        int yLeftBottom = static_cast<int>(detectionMat.at<float>(i, 4) * image.rows);
        int xRightTop = static_cast<int>(detectionMat.at<float>(i, 5) * image.cols);
        int yRightTop = static_cast<int>(detectionMat.at<float>(i, 6) * image.rows);
 
        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: " << (double)t.getTimeMilli() / t.getCounter() << " ms (average from " << t.getCounter() << " iterations)" << std::endl;
	
	imshow("Image", image);
	waitKey(0);
	//system("pause");
	return 0;
}

(4)目标分类示例2
Opencv学习笔记 DNN模块调用Tensorflow的mobilenet对象检测模型_bashendixie5的博客-CSDN博客

https://blog.csdn.net/bashendixie5/article/details/109705409文章来源地址https://www.toymoban.com/news/detail-478409.html

到了这里,关于OpenCV中blobFromImage函数详细解释的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OPENCV 编译选项以及解释

    cmake编译以及模块介绍,后面遇到没有的会继续再补充 CMAKE_BUILD_TYPE:指定构建类型,如Debug、Release等。 CMAKE_INSTALL_PREFIX:指定安装目录。 BUILD_SHARED_LIBS:设置为ON时,构建共享库;设置为OFF时,构建静态库。 BUILD_WITH_STATIC_CTR:当为ON是,构建静态运行时库(MT/MTd),设置为

    2024年02月06日
    浏览(28)
  • realloc函数用法解释

    realloc函数是将数组扩容的一个函数 用法:指针名=(数据类型*)realloc(要改变内存大小的指针名,新的大小)。 具体工作方法: 假设有一个p指针指向一个数组空间,如下图所示 想在想要使这个数组的空间变为原来的2倍,realloc函数就会在p指向的这个数组空间后面申请一段

    2024年02月12日
    浏览(45)
  • SiLu激活函数解释

    在yolo v5中,我们使用了SiLu激活函数 首先,了解一下激活函数的作用: 激活函数在神经网络中起到了非常重要的作用。以下是激活函数的一些主要功能: 引入非线性:激活函数的主要目标是在模型中引入非线性。这是因为,如果没有激活函数,无论神经网络有多少层,它都

    2024年02月07日
    浏览(29)
  • matlab中repmat()函数解释

    repmat意思是 复制和平铺矩阵,何为平铺?举个简单例子   如上述结果可知,其将矩阵(0  1)复制以及向右向下平铺成一个以矩阵(0  1)为单位的33阶的矩阵。 故总结一般repmat函数有如下两种形式:                                             A=[1,2,3,4]  repmat(A,3)

    2024年02月11日
    浏览(23)
  • LLama的激活函数SwiGLU 解释

    目录 Swish激活函数 1. Swish函数公式 LLaMA模型中的激活函数 1. SwiGLU激活函数 2. SwiGLU激活函数的表达式 3. SwiGLU激活函数的优势 Swish激活函数 Swish是一种激活函数,其计算公式如下: 1. Swish函数公式 Swish(x) = x * sigmoid(x) 其中,sigmoid(x)是sigmoid函数,计算公式为: sigmoid(x) = 1 / (1 +

    2024年04月24日
    浏览(23)
  • typedef函数代码段解释以及部分Windows下的系统函数

    在 C/C++ 中,typedef 用于创建类型别名,它可以让你为一个已有的数据类型定义一个新的名称,从而使代码更加清晰、易读,也可以简化类型的声明和使用。 这段代码用 typedef 定义了一个函数指针类型 LPSDOLInitialize ,该函数指针指向一个函数,该函数接受一个指向 SDOLAppInfo 结

    2024年02月12日
    浏览(31)
  • cc攻击详细解释

    CC攻击是指利用多个计算机或其他设备模拟真实用户的行为来进行刷流量的攻击行为。这种攻击的目的通常是为了使服务器的资源耗尽,从而使得服务器无法正常工作。CC攻击可以通过多种方式实现,例如利用计算机病毒或其他恶意软件来感染计算机,或者通过分布式网络来协

    2024年02月13日
    浏览(26)
  • 动态规划【DP】详细解释

    动态规划,英文简称DP,是一种常见的算法设计思想。 它通常被应用于需要求解最优化问题的场景中。其核心思想是将原问题分解成若干个子问题进行求解,并将子问题的解记录下来,避免重复计算。 动态规划的常见四步骤为:定义状态;设计状态转移方程;给定边界条件;

    2024年02月05日
    浏览(28)
  • npm 命令及其详细解释

    npm init 用途:用于初始化一个新的 Node.js 项目,并生成 package.json 文件。 详解:该命令会引导您填写项目的基本信息,如项目名称、版本、描述等,并创建 package.json 文件以保存这些信息。 npm install package 用途:用于安装指定的 Node.js 包。 详解:执行该命令将会下载并安装指

    2024年04月15日
    浏览(24)
  • Git——分支(详细解释)

    目录 一、概念  1.1 服务器运行模式  1.2  分支概念  1.3 分支的好处 二、分支相关操作  2.1 分支操作  2.2 查看当前分支  2.3 创建分支  2.4 切换分支 2.4.1 切换分支 2.4.2  修改代码并提交(完整过程) 三、合并分支   3.1 正常合并   3.2 冲突合并(企业常见)  3.2.1 演示冲突

    2024年02月02日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包