视音频数据处理入门:I420 图像90° 、180°、270°旋转和左右镜像翻转

目录

一、旋转原理

顺时针方向旋转90度

顺时针方向旋转180度

顺时针方向旋转270度

镜像翻转

二、I420旋转原理

原图介绍

I420顺时针方向旋转90度

旋转90度概述

顺时针旋转90度代码

I420顺时针方向旋转180度

旋转180度概述

顺时针旋转180度代码

 顺时针旋转180度效果

 I420顺时针方向旋转270度

旋转180度概述

顺时针旋转270度代码

 I420左右镜像翻转

顺时针镜像翻转度代码

 三、代码路径


一、旋转原理

      图像旋转就是对应像素点的位置的改变,把对应的像素点修改到指定位置即可实现90度、180度、270度旋转。如下图以4x6为例,每个格子代表一个像素点,格子里面的数字代表当前像素的位置;

                                               

                                                                 SRC

顺时针方向旋转90度

我们以上图为例,顺时针方向旋转90度为例,说明旋转90原理;顺时针方向旋转90度,则宽和高互换,由原来4x6变为6x4;SRC[0]的位置被SRC[20]所替代,形成Rotate90[0],以此类推;最终形成图Rotate90的效果。

                                      

                                                                Rotate90

SRC像素对应的内存摆放位置如下:

 Rotate90像素对应的内存摆放位置如下:

经过对比发现Rotate90第index_{Rotate90}(i_{d} x W_{d} + j_{d})个像素点对应SRC的应该为第

index_{src}(H_{src} - j_{d} + i_{d}) ,其中因为进行了90°顺时针旋转所以W_{d}的值为H_{src}

可以得出如下公式:

Rotate90[i,j] =  SRC[H_{src} - j,i];

顺时针方向旋转180度

我们以SRC图顺时针方向旋转180度为例,说明旋转180原理;顺时针方向旋转180度,则宽和高不发生改变,还是原来的4x6;SRC[0]的位置被SRC[23]所替代,形成Rotate180[0],以此类推;最终形成图Rotate180的效果。

                                          

                                                         Rotate180

 SRC像素对应的内存摆放位置如下:

 Rotate180像素对应的内存摆放位置如下:

经过对比发现Rotate180第index_{Rotate180}个像素点对应SRC的应该为第

 (W_{src}XH_{src} - index_{Rotate180})。

可以得出如下公式:

Rotate180[i] =  SRC[W_{src}XH_{src} - i];

顺时针方向旋转270度

我们以SRC图顺时针方向旋转270度为例,说明旋转270原理;顺时针方向旋转270度,则宽和高互换,由原来4x6变为6x4;SRC[0]的位置被SRC[3]所替代,形成Rotate270[0],以此类推;最终形成图Rotate270的效果。

                                   

                                                           Rotate270

 SRC像素对应的内存摆放位置如下:

 Rotate270像素对应的内存摆放位置如下:

 经过对比发现Rotate270第index_{Rotate}(i_{d},j_{d})个像素点对应SRC的应该为第 

index_{src}(j_{d},W-i_{d})。

可以得出如下公式:

Rotate270[i,j] =  SRC[ j x W_{src} ,W_{src}- i];

镜像翻转

我们以SRC图镜像翻转为例,说明镜像翻转原理,宽和高不发生改变,还是原来的4x6;SRC[0]的位置被SRC[3]所替代,形成RotateMirror[0],以此类推;最终形成图RotateMirror的效果。

                                              

                                                          RotateMirror

 SRC像素对应的内存摆放位置如下:

 RotateMirror像素对应的内存摆放位置如下:

 经过对比发现RotateMirror第index_{Rotate}(i_{d},j_{d})个像素点对应SRC的应该为第 

index_{src}(W-i_{d},j_{d})。

可以得出如下公式:

Rotate270[i,j] =  SRC[ W_{src} -i ,j];

二、I420旋转原理

原图介绍

以I420宽高为4x8的图为例,Y0~Y31代表Y分量;U0~U7代表U分量;V0~V7代表V分量;

原图如下: 

                             

                                                                  I420 SRC

I420顺时针方向旋转90度

旋转90度概述

我们以上图为例,I420顺时针方向旋转90度为例,说明I420顺时针方向旋转90原理;I420顺时针方向旋转90度,则宽和高互换,由原来4x8变为8x4;Y[0]的位置被Y[24]所替代,U[0]的位置被U[4]所替代,V[0]的位置被V[4]所替代,形成I420Rotate90[0],以此类推;最终形成图I420Rotate90的效果。

                                              

                                                          I420Rotate90 

 I420 SRC对应的内存摆放位置如下:

  I420Rotate90对应的内存摆放位置如下:

可以得出如下公式:

 I420Rotate90_Y[i,j] =  SRC_Y[H_{src} - j,i];

 I420Rotate90_U[i,j] =  SRC_U[H_{src}/2 - j,i];

I420Rotate90_V[i,j] =  SRC_V[H_{src}/2 - j,i]; 

顺时针旋转90度代码

void RotateI420(uint8_t* src_y, uint8_t* src_u, uint8_t* src_v,
	uint8_t* dst_y, uint8_t* dst_u, uint8_t* dst_v,
	uint32_t width, uint32_t height, int degree)
{	
    if (degree == kRotate90) 
    {
	   // 第一步我们只转Y
	   // 旋转90度
		int index = 0;
		for (int i = 0; i < width; ++i) {
			for (int j = height - 1; j >= 0; --j) {
				dst_y[index++] = src_y[j * width + i];
			}
		}
        // 第二步我们只转UV
		int uv_index = 0;
		for (int i = 0; i < width / 2; i++) {
			for (int j = height / 2 - 1; j >= 0; j--)
			{
				dst_u[uv_index] = src_u[width / 2 * j + i];
				dst_v[uv_index] = src_v[width / 2 * j + i];
				uv_index++;
			}
		}
	}
}

 顺时针旋转90度效果

       

                                                              原图 

                             

                                                    顺时针旋转90°

I420顺时针方向旋转180度

旋转180度概述

我们以I420原图为例,I420顺时针方向旋转180度为例,说明旋转180原理;顺时针方向旋转180度,则宽和高不发生改变,还是原来的4x8;Y[0]的位置被Y[31]所替代,U[0]的位置被U[7]所替代,V[0]的位置被V[7]所替代,以此类推;最终形成图I420Rotate180的效果。

                      

                                                  I420Rotate180

  I420 SRC对应的内存摆放位置如下:

  I420Rotate180对应的内存摆放位置如下:

可以得出如下公式:

 I420Rotate180_Y[i,j] =  SRC_Y[ i,w - j];

 I420Rotate180_U[i,j] =  SRC_U[i,W/2 - j];

I420Rotate180_V[i,j] =  SRC_V[i,W/2 - j]; 

顺时针旋转180度代码

void RotateI420(uint8_t* src_y, uint8_t* src_u, uint8_t* src_v,
	uint8_t* dst_y, uint8_t* dst_u, uint8_t* dst_v,
	uint32_t width, uint32_t height, int degree)
{
	if (degree == kRotate180) {
		// 第一步我们只转Y
	    // Y旋转180度
		int index = 0;
		for (int i = width * height-1; i >= 0 ; --i) {
			dst_y[index++] = src_y[i];
		}
		// 第一步我们只转UV
	    // UV旋转180度
		int uv_index = 0;
		for (int i = width / 2 * height / 2; i >= 0; i--) {
			dst_u[uv_index] = src_u[i];
			dst_v[uv_index] = src_v[i];
			uv_index++;
		}
	}
}

 顺时针旋转180度效果

       

                                                                原图 

       

 I420顺时针方向旋转270度

旋转180度概述

我们以上图为例,I420顺时针方向旋转270度为例,说明I420顺时针方向旋转270原理;I420顺时针方向旋转270度,则宽和高互换,由原来4x8变为8x4;Y[0]的位置被Y[7]所替代,U[0]的位置被U[3]所替代,V[0]的位置被V[3]所替代,形成I420Rotate270[0],以此类推;最终形成图I420Rotate270的效果。

                                               

                                                          I420Rotate270

  I420 SRC对应的内存摆放位置如下:

  I420Rotate270对应的内存摆放位置如下:

可以得出如下公式:

 I420Rotate270_Y[i,j] =  SRC_Y[ i * w,j];

 I420Rotate270_U[i,j] =  SRC_U[i * W/2, j];

I420Rotate270_V[i,j] =  SRC_V[i * W/2 , j]; 

顺时针旋转270度代码

void RotateI420(uint8_t* src_y, uint8_t* src_u, uint8_t* src_v,
	uint8_t* dst_y, uint8_t* dst_u, uint8_t* dst_v,
	uint32_t width, uint32_t height, int degree) 
{
   if (degree == kRotate270)
   {
		// 第一步我们只转Y
	    // 旋转270度
		int index = 0;
		for (int i = width-1; i >= 0; --i) {
			for (int j = 0; j < height; ++j) {
				dst_y[index++] = src_y[j * width+i];
			}
		}
		// 第一步我们只转UV
	    // 旋转270度
		int uv_index = 0;
		for (int i = width / 2-1; i >= 0; i--) {
			for (int j =  0; j< height / 2; j++)
			{
				dst_u[uv_index] = src_u[width / 2 * j+i];
				dst_v[uv_index] = src_v[width / 2 * j+ i];
				uv_index++;
			}
		}
	}
}

 顺时针旋转270度效果

                                                           原图

                                     

                                                               I420Rotate270  

 I420左右镜像翻转

我们以I420原图为基础,进行左右镜像翻转为例,说明左右镜像翻转原理;镜像翻转则宽和高不发生改变,还是原来的4x8;Y[0]的位置被Y[7]所替代,U[0]的位置被U[3]所替代,V[0]的位置被V[3]所替代,以此类推;最终形成图I420RotateMirror的效果。

                            

                                                           I420RotateMirror

 I420 SRC对应的内存摆放位置如下:

  I420RotateMirror对应的内存摆放位置如下:

可以得出如下公式:

I420RotateMirror_Y[i,j] =  SRC_Y[ i , w-j];

I420RotateMirror_U[i,j] =  SRC_U[i , W/2- j];

I420RotateMirror_V[i,j] =  SRC_V[i , W/2 - j]; 

顺时针镜像翻转度代码

void RotateI420(uint8_t* src_y, uint8_t* src_u, uint8_t* src_v,
	uint8_t* dst_y, uint8_t* dst_u, uint8_t* dst_v,
	uint32_t width, uint32_t height, int degree)
{
    if (degree == kRotate90) {
		// 第一步我们只转Y
		int index = 0;
		for (int i = 0; i < width; ++i) {
			for (int j = height - 1; j >= 0; --j) {
				dst_y[index++] = src_y[j * width + i];
			}
		}

		int uv_index = 0;
		for (int i = 0; i < width / 2; i++) {
			for (int j = height / 2 - 1; j >= 0; j--)
			{
				dst_u[uv_index] = src_u[width / 2 * j + i];
				dst_v[uv_index] = src_v[width / 2 * j + i];
				uv_index++;
			}
		}
	}
}

左右镜像翻转效果

 

                                                           原图

 

 三、代码路径

csdn:https://download.csdn.net/download/u011645307/21019241

github:https://github.com/liangqidong/I420rotate

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值