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

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

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

  1. 不占用额外内存空间能否做到 将图像旋转90度 N &#215; N矩阵表示的图像,其中每个像素的大小为4字节

    给定一幅由N × N矩阵表示的图像,其中每个像素的大小为4字节,编写一种方法,将图像旋转90度. 不占用额外内存空间能否做到? 示例 1: 给定 matrix = [ [1,2,3], [4,5,6] ...

  2. EasyPusher手机直播编码推送之图像旋转90度后画面重复的问题

    本文转自EasyDarwin开源团队开发Holo的博客:http://blog.csdn.net/holo_easydarwin 最初在做EasyPusher手机直播的时候遇到过一个问题:手机竖屏推送 ...

  3. EasyPusher手机直播图像旋转90度后画面重复的问题

    本文转自:http://blog.csdn.net/holo_easydarwin/article/details/51147379 最初在做EasyPusher手机直播的时候遇到过一个问题:手机竖屏 ...

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

    在fbc_cv库中,提供了对图像进行任意角度旋转的函数rotate,其实内部也是调用了仿射变换函数warpAffine.如果图像仅是进行90度倍数的旋转,是没有必要用warpAffine函数的.这里通 ...

  5. [google面试CTCI] 1-6.图像旋转问题

    [字符串与数组] Q:Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes, wr ...

  6. python-Day4-迭代器-yield异步处理--装饰器--斐波那契--递归--二分算法--二维数组旋转90度--正则表达式

    本节大纲 迭代器&生成器 装饰器  基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - ...

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

    You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). ...

  8. 基于均值坐标(Mean-Value Coordinates)的图像融合算法的优化实现

    目录 1. 概述 2. 实现 2.1. 原理 2.2. 核心代码 2.3. 第二种优化 3. 结果 1. 概述 我在之前的文章<基于均值坐标(Mean-Value Coordinates)的图像 ...

  9. PyOpenCV图像逆时针旋转90度

    warpAffine方法效果很搓,留下大片黑色区域. 使用flip和transpose可以实现逆时针旋转90度.先flip或先transpose均可. #coding:utf-8 import cv2 ...

随机推荐

  1. <VS2010>混合模式程序集是针对“v2.0”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集

    在把以前写的代码生成工具从原来的.NET3.5升级到.NET4.0时,将程序集都更新后,一运行程序在一处方法调用时报出了一个异常: 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有 ...

  2. Ubuntu加入opencv库的环境变量

    1.用gedit打开/etc/ld.so.conf 终端输入: sudo gedit /etc/ld.so.conf 文件末行加入:include /usr/loacal/lib .然后终端执行指令: ...

  3. jQuery轮播图(手动点击轮播)

    下面来看看最终做的手动点击轮播效果: 一.原理说明 (1)首先是轮播图的架构,我采用了一个最外边的大div包住两个小div,一个小div里面放四张图片,另一个小div里面放四个数字按钮 (2)对最外边 ...

  4. redis 持久化策略、aof配置、测试、手动持久化、aof文件体积优化

    redis持久化策略 1.数据文件.rdb 2.更新日志.aof 设置aof 1.命令方式config set appendonly noconfig rewrite2.配置文件方式 redis持久化 ...

  5. main方法之args参数

    public class Demo { public static void main (String[] arr) { if (arr.length < 3) { System.out.pri ...

  6. 探索ORM之iBati(一)

    ibatis   iBATIS一词来源于“internet”和“abatis”的组合,是一个由Clinton Begin在2001年发起的开放源代码项目.最初侧重于密码软件的开发,现在是一个基于Jav ...

  7. springboot学习入门之四---开发Web应用之Thymeleaf篇

    http://tengj.top/2017/03/13/springboot4/ 1项目结构 说明: root package结构:com.dudu 应用启动类Application.java置于ro ...

  8. numpy meshgrid 和 mgrid 的两个简单实例和解析

    numpy.meshgrid 和 numpy.mgrid 用于返回包含坐标向量的坐标矩阵. 当坐标矩阵为二维时, 可用于在图像变形时构建网格. 实例一 from __future__ import p ...

  9. TFS工具(tf.exe)使用与强制解除锁定签出

    在工作区 NTP01_SUNTAI 中,NTP01TFSUser 为 签出 锁定了项 $/NTP01/EIPD/EIPD.Client/Views/Courseware/EditorOne.xaml. ...

  10. 实用vim 130+命令

    基本命令 :e filename Open filename for edition :w Save file :q Exit Vim :q! Quit without saving :x Write ...