Dlib是一个包含机器学习算法的C++开源工具包。在使用过程中遇到各种图像格式转换接口,为了在之后的使用过程中方便查询,现在将平时用到的接口再这里做一个集锦,后续不断更新……
yuv转matrix
/********************************************************************************
功能 : YUV数据转转换为matrix
输入参数 : YUV数据,图片高,宽,补位,格式
返回值 : matrix<rgb_pixel>, 图片YUV数据转换成matrix 格式返回
*********************************************************************************/
matrix<rgb_pixel> sc_yuv_2_matrix(unsigned char * yuvData, int iHeight, int iWidth, int iStride, int iFormat)
{
matrix<rgb_pixel> img;
img.set_size(iHeight, iWidth);
if(NULL == yuvData )
{
cout << "YUV data error, Parameter is NULL !" << endl;
exit(1);
}
int k = 0;
for (int i = 0; i < iHeight; i++)
{
for (int j = 0; j < iWidth; j++, k++)
{
rgb_pixel p((unsigned char)yuvData[k], (unsigned char)yuvData[k], (unsigned char)yuvData[k]);
img(i, j) = p;
}
}
return img;
}
matrix转为yuv格式
unsigned char *sc_matrix_2_yuv(matrix<rgb_pixel> img, int iHeight, int iWidth)
{
int yuvLen = iHeight * iWidth * 3 / 2; //YUVI420格式
unsigned char *yuvData = new unsigned char [yuvLen];
unsigned char *yData = yuvData;
unsigned char *uData = yuvData + iHeight * iWidth;
unsigned char *vData = yuvData + iHeight * iWidth * 5 / 4;
for(int i = 0; i < iHeight; i++)
{
for(int j = 0; j < iWidth; j++)
{
rgb_pixel p = img(i, j);
int pos = i * iWidth + j;
unsigned char y = (unsigned char)( ( 66 * p.red + 129 * p.green + 25 * p.blue + 128) >> 8) + 16 ;
unsigned char u = (unsigned char)( ( -38 * p.red - 74 * p.green + 112 * p.blue + 128) >> 8) + 128 ;
unsigned char v = (unsigned char)( ( 112 * p.red - 94 * p.green - 18 * p.blue + 128) >> 8) + 128 ;
yData[pos] = y;
if( (i % 2 == 0) && (j % 2 == 0) )
{
if (u > 255)
{
u = 255;
}
if (u < 0)
{
u = 0;
}
*(uData++) = u;
}
else
{
if(j % 2 == 0)
{
if(v > 255)
{
v = 255;
}
if(v < 0)
{
v = 0;
}
*(vData++) = v;
}
}
}
}
return yuvData;
}
yuv数据转为matrix rgb
matrix<rgb_pixel> sc_yuv_2_matrix_rgb(unsigned char *yuvData, int iHeight, int iWidth)
{
matrix<rgb_pixel> img;
img.set_size(iHeight, iWidth);
if (yuvData)
{
const long len = iWidth * iHeight;
unsigned char *yData, *uData, *vData;
unsigned char Y , U, V;
int R, G, B;
yData = yuvData;
uData = &yuvData[len];
vData = &yuvData[len*5/4];
int yIdx,uIdx,vIdx,idx;
for (int i = 0; i < iHeight; i++)
{
for (int j = 0; j < iWidth; j++)
{
yIdx = i * iWidth + j;
uIdx = (i/2) * (iWidth/2) + (j/2);
vIdx = uIdx;
Y = yData[yIdx];
U = uData[uIdx];
V = vData[vIdx];
R = Y + 1.403 *(V-128);
G = Y - 0.34414* (U-128) - 0.71414* (V-128);
B = Y + 1.772 *(U-128);
R = R < 0 ? 0 : R;
G = G < 0 ? 0 : G;
B = B < 0 ? 0 : B;
R = R > 255 ? 255 : R;
G = G > 255 ? 255 : G;
B = B > 255 ? 255 : B;
rgb_pixel p(R, G, B);
img(i, j) = p;
}
}
}
return img;
}
argb数据转换为matrix格式
matrix<rgb_pixel> sc_argb_2_matrix(unsigned char *argb, int height, int width, int channels)
{
matrix<rgb_pixel> img;
img.set_size(height, width);
if (argb)
{
int h = height;
int w = width;
int c = channels;
int i, j;
float R, G, B;
for (j = 0; j < h; j++)
{
for (i = 0; i < w; i++)
{
R = argb[j*w*c + i*c+2];
G = argb[j*w*c + i*c+1];
B = argb[j*w*c + i*c];
rgb_pixel p(R, G, B);
img(j, i) = p;
}
}
}
return img;
}
argb数据保存为jpeg图片
int sc_argb_2_jpeg(unsigned char *argb, int width, int height, int channels, RECT *rect, char *path)
{
if (NULL == argb)
{
return -1;
}
printf("[%s]", path);
printf("rect :[%d %d %d %d]\n", rect[0].x, rect[0].y,rect[1].x,rect[1].y);
rectangle drect;
drect.left() = rect[0].x;
drect.top() = rect[0].y;
drect.right() = rect[1].x;
drect.bottom() = rect[1].y;
matrix<rgb_pixel> img_rgb = sc_argb_2_matrix(argb, height, width, channels);
dlib::draw_rectangle(img_rgb, drect, dlib::rgb_pixel(255, 255, 0), 1);
save_jpeg(img_rgb, path, 100);
return 0;
}
压缩YUV数据
/********************************************************************************
功能 : 压缩YUV数据图片
输入参数 : YUV数据,图片高,宽,最大边长
输出参数 : 压缩之后的 宽、高、压缩率
返回值 : 返回压缩之后的YUV数据图片
*********************************************************************************/
uint8_t* sc_resize(uint8_t* src, int width, int height, int *newW, int *nweH, float *pScale, int maxSide)
{
int originWidth = width;
int originHeight = height;
int originMaxSide = max(originWidth, originHeight); //最大边长
float scale = 0;
int newWidth = width;
int newHeight = height;
uint8_t *oriYuv = src;
// 设置缩放比例,加速检脸速度
if (maxSide > 0 && maxSide < originMaxSide)
{
scale = maxSide / (double) originMaxSide;
newWidth = originWidth * scale;
newHeight = originHeight * scale;
*pScale = scale;
}
*newW = newWidth;
*nweH = newHeight;
uint8_t *newYuv = (uint8_t*)malloc(sizeof(uint8_t) * newWidth * newHeight);
float cosHarfWidth = newWidth * 0.5 * 1;
float sinHarfWidth = newWidth * 0.5 * 0;
float cosHarfHeight = newHeight * 0.5 * 1;
float sinHarfHeight = newHeight * 0.5 * 0;
double invertScale = 1 / scale;
for (int y = 0, h = newHeight; y < h; y++)
{
for (int x = 0, w = newWidth; x < w; x++)
{
float oX = ( x - cosHarfWidth ) * invertScale + originWidth * 0.5;
float oY = abs( ( y - cosHarfHeight) * invertScale + originHeight * 0.5);
int x1, x2, y1, y2;
float x1y1, x2y1, x1y2, x2y2;
uint8_t val = 0;
x1 = (int)oX;
y1 = (int)oY;
x2 = x1 + 1;
y2 = y1 + 1;
x1 = max(0, min(x1, originWidth - 1));
x2 = max(0, min(x2, originWidth - 1));
y1 = max(0, min(y1, originHeight - 1));
y2 = max(0, min(y2, originHeight - 1));
//每个点权重
x1y1 = (1.0 - oX + x1) * (1.0 - oY + y1);
x2y1 = (oX - x1) * (1.0 - oY + y1);
x1y2 = (1.0 - oX + x1) * (oY - y1);
x2y2 = (oX - x1) * (oY - y1);
//val = src[y1*newHeight+x1]
val = oriYuv[y1 * width + x1] * x1y1;
val += oriYuv[y1 * width + x2] * x2y1;
val += oriYuv[y2 * width + x1] * x1y2;
val += oriYuv[y2 * width + x2] * x2y2;
newYuv[y * newWidth + x] = val;
}
}
return newYuv;
}