STBI图像数据和darknet中image数据类型之间的转换
前言
STBI图像数据和darknet中image数据类型之间的转换
image2stbi file: src/image.c function: save_image_options
for(k = 0; k < im.c; ++k){ for(i = 0; i < im.w*im.h; ++i){ data[i*im.c+k] = (unsigned char) (255*im.data[i + k*im.w*im.h]); } }
其中,data是stbi数据,im是image数据类型,可以看出STBI数据存储方式和opencv类似,不过是RGB顺序,opencv中图像数据的存储方式如下图所示。
darknet中的image数据类型
typedef struct { int w; int h; int c; float *data; } image;
stbi2image file: src/image.c function: load_image_stb
for(k = 0; k < c; ++k){ for(j = 0; j < h; ++j){ for(i = 0; i < w; ++i){ int dst_index = i + w*j + w*h*k; int src_index = k + c*i + c*w*j; im.data[dst_index] = (float)data[src_index]/255.; } } }
darknet中image数据类型和opencv数据类型之间的转换
mat_to_image file: src/image_opencv.cpp load_image_cv
image mat_to_image(Mat m) { int h = m.rows; int w = m.cols; int c = m.channels(); image im = make_image(w, h, c); unsigned char *data = (unsigned char *)m.data; int step = m.step; int i, j, k; for(i = 0; i < h; ++i){ for(k= 0; k < c; ++k){ for(j = 0; j < w; ++j){ im.data[k*w*h + i*w + j] = data[i*step + j*c + k]/255.; } } } rgbgr_image(im); return im; }
image_to_mat file: src/image_opencv.cpp show_image_cv
Mat image_to_mat(image im) { image copy = copy_image(im); constrain_image(copy); if(im.c == 3) rgbgr_image(copy); Mat m(cv::Size(im.w,im.h), CV_8UC(im.c)); int x,y,c; int step = m.step; for(y = 0; y < im.h; ++y){ for(x = 0; x < im.w; ++x){ for(c= 0; c < im.c; ++c){ float val = im.data[c*im.h*im.w + y*im.w + x]; m.data[y*step + x*im.c + c] = (unsigned char)(val*255); } } } free_image(copy); return m; }
分析源码,感觉图像数据之间的转换没有问题,为什么show的时候显示图像颜色不正常呢????
不同的图像数据类型在内存中的数据存储方式总结
STBI:RGB RGB RGB的顺序排列,共W列H行;
opencv:BGR BGR BGR的顺序排列,共W列H行;
image:3个W列H行的顺序排列,依次表示RGB;
参考
1. 【我的C/C++语言学习进阶之旅】介绍一下NDK开发之C的简单易用图像库stb;
2. stb_github;
3. opencv-how-image-stored-memory;
完