基于C语言软件实现一张YUV420图像特定区域打马赛克

1)基于C语言软件实现某一张YUV420图像特定区域打马赛克,分享给将要学习或者正在学习图像开发的同学。后面贴完整源码。

2)适用于对C语言有基本的认识,以及对Linux驱动知识有基本的掌握能力。

4)内容属于原创,若转载,请说明出处。

5)提供相关问题有偿答疑和支持。

下面是具体实现:

1)取一张YUV420的图像NV12的格式

8c251bf8cd5848b1bdd67fdb6ebf7121.png

2)将上图的人脸打马赛克

4367d7fa75cc470398cf3624cce5edb6.png

3)主要实现的code

定义马赛克的位置以及大小,和打码的宏块数目:

#define YUV420_WIDTH	1920
#define YUV420_HIGH		1080
#define YUV420_SIZE		(YUV420_WIDTH * YUV420_HIGH * 3/2)

#define MOSAIC_WIDTH	500
#define MOSAIC_HIGH		500
#define MOSAIC_X		750
#define MOSAIC_Y		150
#define MOSAIC_DIV		20 //25x25
#define MOSAIC_XN		(MOSAIC_WIDTH/MOSAIC_DIV)
#define MOSAIC_YN		(MOSAIC_HIGH/MOSAIC_DIV)

#define MOSAIC_SIZE		(MOSAIC_WIDTH * MOSAIC_HIGH * 3/2)

对原始的YUV进行crop:

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;
}

对单个宏块进行填充:主要是取每一个小宏块的左上角的一个像素填充整个小宏块

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;
	}

}

完整代码:

eea7b04f2d8344ec825d57a2a0344c56.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值