YUV420图像旋转90算法的优化

在做android摄像头捕获时,发现从android摄像头出来的原始视是逆时针旋转了90度的,所以须要把它顺时针旋转90。android视频支持的是NV21格式,它是一种YUV420的格式。当然,始果你用的是android
sdk的话,当中image就提供这个能力。可是我是在ndk下开发,没有找到对应的功能(假设你知道请告诉我)。

我本想用开源的图像处理库(opencv)做旋转,可是opencv仅仅能处理bmp的图像。这种话,须要先把NV21转换成BMP32。然后再做旋转。所以要操作两次,效率肯定低。最后也没找到好的方法(假设你知道一次用opencv做YUV420格式的旋转,请你告诉我)。所以仅仅有自己写一个。

先从网上搜索了一个:

void CTool::YUV420spRotate90(uchar *des, uchar *src,int width,int height)
{
int wh = width * height;
//旋转Y
int k = 0;
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++)
{
des[k] = src[width * j + i];
k++;
}
}

for(int i = 0; i < width; i += 2) {
for(int j = 0; j < height / 2; j++)
{
des[k] = src[wh+ width * j + i];
des[k+1] = src[wh + width * j + i + 1];
k+=2;
}
}
}

在android上执行了一下,发现视频很卡。所以仅仅有自己优化了。这段代码里有乘法,优化的重点就是去掉乘法用加法取代:

void CTool::YUV420spRotate90(uchar *dst, const uchar *src, int srcWidth, int srcHeight)
{
static int nWidth = 0, nHeight = 0;
static int wh = 0;
static int uvHeight = 0;
if(srcWidth != nWidth || srcHeight != nHeight)
{
nWidth = srcWidth;
nHeight = srcHeight;
wh = srcWidth * srcHeight;
uvHeight = srcHeight >> 1;//uvHeight = height / 2
}

//旋转Y
int k = 0;
for(int i = 0; i < srcWidth; i++) {
int nPos = 0;
for(int j = 0; j < srcHeight; j++) {
dst[k] = src[nPos + i];
k++;
nPos += srcWidth;
}
}

for(int i = 0; i < srcWidth; i+=2){
int nPos = wh;
for(int j = 0; j < uvHeight; j++) {
dst[k] = src[nPos + i];
dst[k + 1] = src[nPos + i + 1];
k += 2;
nPos += srcWidth;
}
}
return;
}


逆时针旋转90度:

void CTool::YUV420spRotateNegative90(uchar *dst, const uchar *src, int srcWidth, int height)
{
static int nWidth = 0, nHeight = 0;
static int wh = 0;
static int uvHeight = 0;
if(srcWidth != nWidth || height != nHeight)
{
nWidth = srcWidth;
nHeight = height;
wh = srcWidth * height;
uvHeight = height >> 1;//uvHeight = height / 2
}

//旋转Y
int k = 0;
for(int i = 0; i < srcWidth; i++){
int nPos = srcWidth - 1;
for(int j = 0; j < height; j++)
{
dst[k] = src[nPos - i];
k++;
nPos += srcWidth;
}
}

for(int i = 0; i < srcWidth; i+=2){
int nPos = wh + srcWidth - 1;
for(int j = 0; j < uvHeight; j++) {
dst[k] = src[nPos - i - 1];
dst[k + 1] = src[nPos - i];
k += 2;
nPos += srcWidth;
}
}

return;
}


编译执行,捕获视频显示很流畅 :)

时间: 2024-10-20 14:31:11

YUV420图像旋转90算法的优化的相关文章

将图像旋转90度

题目:给定一幅由N*N矩阵表示的图像,其中每个像素的 大小为4字节,编写一个方法,将图像旋转90度.不占用额外内存空间能否做到? 那么,该如何交换这四条边?一种做法是把上面复制到一个数组中,然后将左边移到上边,下边移到到左边,等等.这需要占用O(N)内存空间.但实际上没有必要, 更好的做法是按索引一个一个进行交换.具体做法如下: for i = 0 to n temp = top[i]; top[i] = left[i]; left[i] = bottom[i]; bottom[i] = rig

通过transpose和flip实现图像旋转90/180/270度

在fbc_cv库中,提供了对图像进行任意角度旋转的函数rotate,其实内部也是调用了仿射变换函数warpAffine.如果图像仅是进行90度倍数的旋转,是没有必要用warpAffine函数的.这里通过transpose和flip函数实现对图像进行顺时针90度.180度.270度的旋转. 用fbc::transpose.fbc::flip和cv::transpose.cv::flip实现的结果是完全一致的. 通过fbc_cv库实现代码如下: #include "test_rotate90.hpp

CC150:将一个矩阵旋转90度

一张图像表示成n X n的矩阵,写一个函数把图像旋转90度.不开辟额外的存储空间 我们假设要将图像逆时针旋转90度.原图如下所示: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 逆时针旋转90度后的图应该是: 4 8 12 16 3 7 11 15 2 6 10 14 1 5 9 13 我们要如何原地进行操作以达到上面的效果呢?可以分两步 第一步交换主对角线两侧的对称元素, 第二步交换第i行和第n-1-i行,即得到结果. 看图示: 原图:           第一

矩阵旋转90度(keep it up)

一张图像表示成NxN的矩阵,图像中每个像素是4个字节,写一个函数把图像旋转90度. 你能原地进行操作吗?(即不开辟额外的存储空间) 这个题第一感觉就是一次交换矩阵的元素: 比如 3*3 矩阵 1 2 3 4 5 6 7 8 9 先处理第一行,一次逆时针旋转四个元素,下面是二次做的 3 2 9          3 6 9 4 5 6          2 5 8 1 8 7          1 4 7 第一次         第二次 如果是5*5的矩阵 1   2   3   4   5 6

每日算法之三十七:Rotate Image (图像旋转)

You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). Follow up: Could you do this in-place? 原地图像顺时针旋转90度.因为要求空间复杂度是常数,因此应该迭代旋转操作. class Solution { public: void rotate(vector<vector<int> > &mat

用OpenCV实现Photoshop算法(一): 图像旋转

最近学习了OpenCV,于是想用它实现Photoshop的主要功能,用于照片处理. 对于一张照片,PS的一般处理步骤包括: 1, 旋转图片,校正位置. 2,剪切,调整大小,重新构图. 3,调整色阶.曲线,使图片曝光正确.对比适中. 4,调整对比度.饱和度 5,印章去掉不想要的东西,液化调整形体线条 6,对于人像图片,美肤.美白 7, 用色彩平衡.可选颜色等调整色调,形成照片调性 8,加一些光效 9,锐化 以后的一系列博文将采用OpenCV逐一实现Photoshop的算法和功能, 并用计算机视觉人

每日算法37:Rotate Image (图像旋转)

You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). Follow up: Could you do this in-place? 原地图像顺时针旋转90度.由于要求空间复杂度是常数,因此应该迭代旋转操作. class Solution { public: void rotate(vector<vector<int> > &mat

图像旋转算法

图像旋转是指把定义的图像绕某一点以逆时针或顺时针方向旋转一定的角度,通常是指绕图像的中心以逆时针方向旋转. 假设图像的左上角为(left, top),右下角为(right, bottom),则图像上任意点(x0, y0)绕其中心(xcenter, ycenter)顺时针旋转θ角度后,新的坐标位置(x′, y′)的计算公式为: xcenter = (right - left + 1) / 2 + left;ycenter = (bottom - top + 1) / 2 + top;x′ = (x

php图像旋转,图片旋转(逆时针90或者顺时针90)

//src 图片完整路径 //$direction 1顺时针90 2 逆时针90 function imgturn($src,$direction=1) { $ext = pathinfo($src)['extension']; switch ($ext) { case 'gif': $img = imagecreatefromgif($src); break; case 'jpg': case 'jpeg': $img = imagecreatefromjpeg($src); break; c