背景:在图像处理领域,往往为了隐私的保护,通常会对某一幅图像打马赛克,或者是对图像的某个区域打马赛克。本节重点主要是C语言实现软件对图像某一区域打马赛克。原理就是将某一打马赛克的区域划分成多个宏块,然后取每一个宏块的左上角的颜色填充整个小宏块。
1)如下是一张1920x1080的YUV NV12的原始图像:input_res1920x1080_pixelFormat11.yuv
2)将以上的人脸区域裁剪下来:mosaic.yuv
3)将人脸区域打马赛克:500x500.bmp
4)相关裁剪的code:
int yuv_crop(char *nv12data, int width, int height, int cropx,
int cropy, char *yuv420pdata, int dscw, int dsch)
{
char *ptry = yuv420pdata, *ptru, *ptrv;
char *nvptr = nv12data + width * height;
ptry = yuv420pdata;
ptru = yuv420pdata + dscw * dsch;
ptrv = yuv420pdata + dscw * dsch + 1;
// copy y
for (int y = cropy; y < dsch + cropy; y++)
{
memcpy(ptry, nv12data + y * width + cropx, dscw);
ptry += dscw;
}
// copy uv
for (int nvy = cropy / 2; nvy < dsch / 2 + cropy / 2; nvy++)
{
for (int nvx = cropx; nvx < dscw + cropx; nvx++)
{
if (nvx % 2 == 0)
{
*ptru = nvptr[nvy * width + nvx];
ptru+=2;
}
else
{
*ptrv= nvptr[nvy * width + nvx];
ptrv+=2;
}
}
}
return 0;
}
static unsigned short yuv_argb(unsigned char y, unsigned char u, unsigned char v)
{
int r, g, b;
unsigned short argb = 0;
r = y + (140 * (v - 128)) / 100; //r
g = y - (34 * (u - 128)) / 100 - (71 * (v - 128)) / 100; //g
b = y + (177 * (u - 128)) / 100; //b
if (r > 255) r = 255;
if (g > 255) g = 255;
if (b > 255) b = 255;
if (r < 0) r = 0;
if (g < 0) g = 0;
if (b < 0) b = 0;
argb = ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
return argb;
}
void fill_pixels(unsigned char *bmp_data, int h, int w, unsigned short font_data)
{
unsigned short *pixel = (unsigned short *)bmp_data;
int pos = (h * MOSAIC_DIV * MOSAIC_WIDTH) + (w * MOSAIC_DIV);
//printf("pos: %d, %d\n", pos, font_data);
for(int i=0; i<MOSAIC_DIV; i++)
{
for(int j=0; j<MOSAIC_DIV; j++)
{
pixel[pos + j] = font_data;
}
pos += MOSAIC_WIDTH;
}
}
static void rgb2bmp(unsigned short *p)
{
int res = -1;
BITMAP_S* bmp = NULL;
char f_name[50];
res = create_bmp_file(MOSAIC_WIDTH, MOSAIC_HIGH, &bmp);
for(int i=0; i<MOSAIC_YN; i++)
{
for(int j=0; j<MOSAIC_XN; j++)
{
//printf("%d ", *p);
fill_pixels((*bmp).bmpData, i, j, *p++);
}
}
//printf("\n");
sprintf(f_name, "%d%s%d%s", MOSAIC_WIDTH, "x", MOSAIC_HIGH, ".bmp");
res = write_bmp_file(bmp, f_name);
}
4)将马赛克图像保存成BMP图像,方便预览,完整源码:本页链接有免费下载