nvjpeg与opencv 图片解码和预处理耗时对比

nvjpeg与opencv 解码和预处理耗时对比

1. opencv c++与python jpeg decode对比

  • 环境

CPU: AMD Ryzen 5 5600X 6-Core Processor 3.70 GHz
内存:32.0 GB
C++ vs2017 MSVC编译器工具集
python 3.6.8
测试图片有两类:

数据集1 血片细胞图片尺寸:2448*2048.
数据集2 网上随机下载的自然风光,人物,汽车等20张图片,尺寸在471 *600 至 2048 *1536之间。

注:图片的大小对测试结果应该有比较大的影响。

  • 核心代码

1. Python

    start_time = time.clock()
    img = cv2.imread(file_name)
    end_time = time.clock()
    total = total + (end_time-start_time)

2. C++

    const auto start_t = std::chrono::high_resolution_clock::now();
	for (size_t i = 0; i < 15; i++)
	{
		//std::cout << files[i].c_str() << std::endl;
		//opencv decode
		cv::Mat image = cv::imread(files[i].c_str());
	}
	const auto end_t = std::chrono::high_resolution_clock::now();
	std::cout << "read image cost:" << std::chrono::duration(end_t - start_t).count() << "ms" << std::endl;

3. 耗时

  • 数据集1 血片图片结果
语言 单张平均耗时(ms) 15张总耗时(ms)
Python 37.90 568.49
C++ 30.92 463.82

注:c++采用release模式,不能用debug。且每次执行时间不一样,多执行几次取了一个中间值。

  • 数据集2 随机下载图片测试结果
语言 单张平均耗时(ms) 20张总耗时(ms)
Python 7.18 143.69
C++ 5.38 107.69

注:cc++采用release模式,不能用debug。且每次执行时间不一样,多执行几次取了一个中间值。

2. opencv c++与python jpeg resize对比

  • 环境与1一致
    resize 的大小都是到(224,224)

  • 核心代码
    1. Python

    start_time = time.clock()
    img = cv2.resize(img,(224,224))
    end_time = time.clock()
    total = total + (end_time-start_time)
    print('costs time : ',total)

2. C++

	std::chrono::duration total;
	for (size_t i = 0; i < 20; i++)
	{
		//std::cout << files[i].c_str() << std::endl;
		//opencv decode
		cv::Mat image = cv::imread(files[i].c_str());
		const auto start_t = std::chrono::high_resolution_clock::now();
		cv::resize(image, resized_image, cv::Size(224, 224));
		const auto end_t = std::chrono::high_resolution_clock::now();
		total = total + (end_t - start_t);
		//std::cout << "read image cost:" << std::chrono::duration(end_t - start_t).count() << "ms" << std::endl;
	}
	std::cout << "read image cost:" << total.count() << "ms" << std::endl;

3. 耗时

  • 数据集1 血片图片结果
语言 单张平均耗时(ms) 15张总耗时(ms)
Python 0.57 8.54
C++ 0.34 5.10

注:c++采用release模式,不能用debug。且每次执行时间不一样,多执行几次取了一个中间值。

  • 数据集2 随机下载图片测试结果
语言 单张平均耗时(ms) 20张总耗时(ms)
Python 0.24 4.98
C++ 0.14 2.87

注:c++采用release模式,不能用debug。且每次执行时间不一样,多执行几次取了一个中间值。

3. NVJPEG与opencv decode对比

  • 1.环境

CPU: AMD Ryzen 5 5600X 6-Core Processor 3.70 GHz
内存:32.0 GB
C++ vs2017 MSVC编译器工具集
NVJPEG 是cuda11.1版本

数据集3:血片图片resize 到不同尺寸保存的图片。[32,64,128,224,360,480,640,720,960,1080,1280,1920,2048,3120]

  • 2.代码

  • NVJPEG Sample 测试代码来自于nvJPEG项目

  • NVJPEG guide

  • 3. C++ opencv 在数据集3测试平均解码时间(ms)

解码方式 32 64 128 224 480 720 960 1080 1280 2048 3120
Opencv(C++) 0.112 0.152 0.330 0.677 2.651 6.021 10.410 12.710 17.295 38.871 79.160
NVJPEG 0.360 0.350 0.380 0.370 0.489 0.640 0.810 1.04 1.28 2.230 2.420

注:nvjpeg 在224及之前的尺寸时间几乎没有差异。

4. NVJPEG与opencv resize对比

  • 在第2点 的基础上增加nvjpeg的测试,环境保持一致。

对于resize 操作使用的是NPP库,基于cuda写的图像处理的库。当我们在做深度学习推理时,需要对图像预处理时,希望推理时预处理与训练是预处理保持一致,那么很显然推理使用cuda加速预处理后希望把数据的排列(如:nchw)保持一致。而如果基于nvjpeg使用cuda处理,数据是按照gpu需要的排列进行计算,因此无论解码和预处理如何在cuda计算,处理完的数据排列必然要清楚,要么就老老实实的转化为cv:mat的方式。
回到测试resize的话题,由于要使用cuda做resize,则需要对输入数据进行排列,最方便的形式就是只用nvjpeg解码,直接加载到cuda内存中,resize也可按照的解码的格式进行resize,因此,resize应该和decode配套使用效率才是最高的。另外,resize结束应该按照什么数据排列作为resize结束呢?按照两种方式,第一是nvjpeg的数据格式作为结束,记为NVJPEG_OUTPUT_BGR,第二是重新排列到cv::Mat格式作为结束,记为cv::Mat

以下测试的内容包括jpeg decode和resize的时间。resize 的大小都是到(224,224)

  • 数据集1 血片图片结果
单张平均耗时(ms) 15张总耗时(ms)
Python 44.47 667
C++ 38.11 571.65
NVJPEG 3.64 54.69
  • 数据集2 随机下载图片测试结果
单张平均耗时(ms) 20张总耗时(ms)
Python 7.65 153.17
C++ 5.72 114.4
NVJPEG 2.63 52.71

注:nvjpeg计算的时间都是计算cuda计算时间,没有考虑初始化准备的时间

5. NVJPEG与opencv decode + resize + encode对比

  • 核心代码
  • C++
#include 
#include 
#include 
#include 

int main(int argc, const char *argv[])
{
	char *filePath = (char*)"D:\\image_decode\\data";
	std::vector files;
	getFiles(filePath, files);
	int img_num = 15;
	cv::Mat resized_image(224, 224, CV_8UC3);
	const auto start_t = std::chrono::high_resolution_clock::now();
	//std::chrono::duration total;
	for (size_t i = 0; i < img_num; i++)
	{
		//std::cout << files[i].c_str() << std::endl;
		//opencv decode
		cv::Mat image = cv::imread(files[i].c_str());
		//const auto start_t = std::chrono::high_resolution_clock::now();
		cv::resize(image, resized_image, cv::Size(224, 224));
		cv::imwrite("result.jpg", resized_image);
		//const auto end_t = std::chrono::high_resolution_clock::now();
		//total = total + (end_t - start_t);
		
	}
	const auto end_t = std::chrono::high_resolution_clock::now();
	std::cout << "read image cost:" << std::chrono::duration(end_t - start_t).count()/ img_num << "ms" << std::endl;
	//std::cout << "read image cost:" << total.count() << "ms" << std::endl;
}
  • 数据集1 血片图片结果
单张平均耗时(ms) 15张总耗时(ms)
Python 45.92 688.82
C++ 39.28 589.2
NVJPEG 3.97 59.63
  • 数据集2 随机下载图片测试结果
单张平均耗时(ms) 20张总耗时(ms)
Python 8.56 171.16
C++ 6.80 136
NVJPEG 2.91 58.18

注:nvjpeg计算的时间都是计算cuda计算时间,没有考虑初始化的时间

思考的问题
数据预处理阶段,resize结束后,还有归一化,nchw排列的计算,这部分还可以可以加速?

你可能感兴趣的:(NVJPEG,Opencv,opencv,人工智能,python)