软件C语言实现一张YUV数据某个区域马赛克算法(mosaic)

背景:在图像处理领域,往往为了隐私的保护,通常会对某一幅图像打马赛克,或者是对图像的某个区域打马赛克。本节重点主要是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图像,方便预览,完整源码:本页链接有免费下载

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值