来源:转载自https://forum.sophgo.com/t/stb-image-jpg-rvv-milkv-duo/240,原作者nihui
stb_image jpg解码 RVV优化和在 milkv-duo 上的测试
GitHub
你可以:
#define STBI_RVV
+ stbi_load
或者你也可以:
cv::imread
已经包含jpg解码RVV优化GitHub
小而美的图像库 stb_image,没有任何依赖,include 一个 .h 文件就能实现 JPG PNG 等常用格式解码
相比于 libjpeg libpng,stb_image 移植极度方便,接口十分简单即 stbi_load
opencv-mobile 项目中的 highgui 模块利用 stb_image 实现图片读写功能
stb_image.h 中有 x86 sse2 和 arm neon 的加速代码,没有 risc-v vector 优化
相当多的 risc-v 芯片带有 npu,但图像解码依旧要靠 cpu,因此十分有必要优化一下下
具体实现细节就不bb了,想了解的人直接看源码
github.com/nihui/opencv-mobile
(什么?你说你 RVV 可以 compress + merge 或者 left shift + widen add 来搞 shuffle?你也不嫌丑?)
简单写个计时函数,循环调用 stbi_load 加载 1280x720 分辨率的 jpg 图片,输出接口耗时(ms)
在 include 前定义 STBI_RVV 开启优化!
#include //gettimeofday()
#include // sleep()
#define STB_IMAGE_IMPLEMENTATION
#define STBI_RVV
#include "stb_image.h"
double get_current_time()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0;
}
int main()
{
for (int i = 0; i < 10; i++)
{
double t0 = get_current_time();
int desired_channels = 3;
int w;
int h;
int c;
unsigned char* pixeldata = stbi_load("in.jpg", &w, &h, &c, desired_channels);
double t1 = get_current_time();
stbi_image_free(pixeldata);
fprintf(stderr, "%.3f\n", t1-t0);
}
return 0;
}
在 milkv-duo 实测下开不开 STBI_RVV 区别
[root@milkv]~# ./stbimage-test
214.697
219.526
214.598
214.787
216.354
214.875
217.516
214.868
217.323
214.912
[root@milkv]~# ./stbimage-test-rvv
149.423
152.059
149.017
148.450
150.817
148.090
148.167
150.507
147.775
147.381
优化后的 stb_image 更新到 opencv-mobile 里头,为 cv::imread
/ cv::imdecode
带来提速,同时保存解码后的图片,验证结果是否一致
#include //gettimeofday()
#include // sleep()
#include
#include
#include
double get_current_time()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0;
}
int main()
{
for (int i = 0; i < 10; i++)
{
double t0 = get_current_time();
cv::Mat bgr = cv::imread("in.jpg", 1);
double t1 = get_current_time();
fprintf(stderr, "%.3f\n", t1-t0);
if (i == 9)
{
cv::resize(bgr, bgr, cv::Size(200, 200));
cv::imwrite("out-rvv.jpg", bgr);
}
}
return 0;
}
在 milkv-duo 实测下开不开 STBI_RVV 区别
[root@milkv]~# LD_LIBRARY_PATH=. ./opencv-mobile-test
279.231
275.922
278.366
275.949
278.956
278.733
275.571
278.167
275.566
279.943
[root@milkv]~# LD_LIBRARY_PATH=. ./opencv-mobile-test-rvv
226.102
221.550
224.004
220.458
223.346
220.088
219.719
221.991
218.758
222.004
opencv-mobile cv::imread 相对于 stb_image stbi_load 多了 memcpy 和 RGB2BGR 转换的代价
RVV优化后的保存图片,md5sum完全一致!
[nihui@nihui-pc build]$ md5sum out*
a70cc79b13daeddd8b20e31a2fd5f0c6 out.jpg
a70cc79b13daeddd8b20e31a2fd5f0c6 out-rvv.jpg
图片内容也是正常的