海思AI芯片(Hi3519A/3559A)方案学习(十一)分析bgr文件格式

前言

  3519A nnie SDK只支持BGR以及yuv格式的数据输入。那么当手头刚好只有jpeg/png等图片文件时,怎么来进行目标识别呢?一般的思路是用opencv来读取图片文件,然后再转换成BGR/YUV等格式,最后扔到NNIE模块来进行深度学习推理。

BGR文件数据格式

nnie sample里面提供的测试图片有后缀名为bgr的文件,例如dog_bick_car.bgr。在sample code里面直接通过fopen fread之类C文件API来读取二进制数据到buffer,然后再调用nnie forward API进行图像识别。 

可是实际应用中,拿到的图片往往是jpeg/png等格式,所以需要先调用opencv库函数进行转换。而要正确的转换,就先要知道bgr文件的数据格式,亦即GBG的排列顺序。下面代码就是将sample里面的bgr按bgrbgrbgr... ...格式重构成Mat类型,然后进行显示,看看显示跟预期是否一致。


        FILE *fp;
	fp = fopen("D:/work/dog_bike_car_416x416.bgr", "rb");
    
        unsigned char img_data[416x416x3];
	fread(img_data, 1, 416x416x3, fp);
	fclose(fp);

        Mat img = Mat(416, 416, CV_8UC3, img_data);
        imshow("hello", img);

结果发现,显示不正确,如下所示:

后来,通过试验,发现它是按BBBB....GGGG....RRRR...排列的。其相应读取转换代码如下:

    //img_data是按BBBB...GGGG...RRRR...排列的(bgr文件格式)
    //img_data_conv按BGRBGRBGR... ...排列的(OPencv Mat排列格式)
    unsigned char img_data[416 * 416 * 3], img_data_conv[416 * 416 * 3];

    FILE *fp;
    fp = fopen("D:/work/dog_bike_car_416x416.bgr", "rb");
	int channels = 3;
	int width = 416;
	int height = 416;
	
	fread(img_data, 1, width*height*channels, fp);
	fclose(fp);
	
	for (int h = 0; h < height; h++)
		for (int w = 0; w < width; w++)
			for (int c = 0; c < channels; c++)
			{
				img_data_conv[h * width * channels + w * channels + c] = img_data[(height * width) * c + h * width + w];

			}
		
	Mat img_test = Mat(height, width, CV_8UC3, img_data_conv);
        imshow("hello", img_test);

其显示如下,是正确的。

 小结

上面代码 写的比较粗糙,硬代码很多,也没考虑效率,大家理解就行。 此外,本文主要是通过实验来明确海思sample里面bgr文件的数据格式, 并没有提供bgrbgr...转换成b...g...r...代码,但是参考上面代码就应该很容易实现,说白了就是一逆过程。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(nnie,3519,sample,bgr,嵌入式AI)