本次整理了顺时针旋转90度、逆时针旋转90度、逆时针旋转180度、逆时针旋转180度再水平翻转、水平翻转。如有有需要请留言,我会再添加其他旋转算法。
算法可以直接看下面的代码,如果需要代码中的yuv420p.yuv文件及vs工程可以到这里下载:https://pan.baidu.com/s/1z2S5o-Oqbf-_oUyFYGz0zg
// Yuv420pRotate.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
// clockwise 顺时针
// contrarotate 逆时针旋转
// flip horizontal 镜像翻转/水平翻转
/**
* 顺时针旋转90。
* 取元素:从左下方第一个点开始,从下往上,从左往右取点;
* 放元素:从左上方第一个位置开始放,从左往右,从上往下;把每一列转换成每一行。
*
* @param yuvFileaName 一帧YUV420P格式的文件
* @param width 图像的宽
* @param height 图像的高
*
* @return 空
*/
void clockwiseRotate90(const char* yuvFileaName, int width, int height){
FILE* fp = NULL;
fopen_s(&fp, yuvFileaName, "rb");
unsigned char* yuvbuf = new unsigned char[width*height * 3 / 2];
fread(yuvbuf, width*height * 3 / 2, 1, fp);
fclose(fp);
int idx = 0;
//Y
unsigned char* dstbuf = new unsigned char[width*height * 3 / 2];
for (int i = 0; i <= width - 1; i++){
for (int j = height - 1; j >= 0; j--){
dstbuf[idx++] = *(yuvbuf + (j*width + i));
}
}
//U
unsigned char* uheader = yuvbuf + width*height;
int hw = width / 2;
int hh = height / 2;
for (int i = 0; i <= hw - 1; i++){
for (int j = hh - 1; j >= 0; j--){
dstbuf[idx++] = *(uheader + (j*hw + i));
}
}
//V
unsigned char* vheader = uheader + width*height / 4;
for (int i = 0; i <= hw - 1; i++){
for (int j = hh - 1; j >= 0; j--){
dstbuf[idx++] = *(vheader + (j*hw + i));
}
}
FILE* fpout = NULL;
fopen_s(&fpout, "clockwiseRotate90.yuv", "wb");
fwrite(dstbuf, width*height * 3 / 2, 1, fpout);
fclose(fpout);
delete[] yuvbuf;
delete[] dstbuf;
}
/**
* 逆时针旋转90。
* 取元素:从右上方第一个点开始,从上往下,从右往左取点;
* 放元素:从左上方第一个位置开始放,从左往右,从上往下;把每一列转换成每一行。
*
* @param yuvFileaName 一帧YUV420P格式的文件
* @param width 图像的宽
* @param height 图像的高
*
* @return 空
*/
void contrarotate90(const char* yuvFileaName, int width, int height)
{
int i, j, k, p;
FILE* fp = NULL;
fopen_s(&fp, yuvFileaName, "rb");
unsigned char* yuvbuf = new unsigned char[width*height * 3 / 2];
fread(yuvbuf, width*height * 3 / 2, 1, fp);
fclose(fp);
unsigned char* dstbuf = new unsigned char[width*height * 3 / 2];
char* dest = (char*)dstbuf;
char* src = (char*)yuvbuf;
// rotate Y
for (j = 0; j < width; j++){
for (i = 1; i <= height; i++){
*dest++ = *(src + i*width - j);
}
}
// rotate U
char *src_u = src + width*height;
for (p = 0; p < width / 2; p++){
for (k = 1; k <= height / 2; k++){
*dest++ = *(src_u + k*width / 2 - p);
}
}
// rotate V
char *src_v = src + width*height * 5 / 4;
for (p = 0; p < width / 2; p++){
for (k = 1; k <= height / 2; k++){
*dest++ = *(src_v + k*width / 2 - p);
}
}
FILE* fpout = NULL;
fopen_s(&fpout, "contrarotate90.yuv", "wb");
fwrite(dstbuf, width*height * 3 / 2, 1, fpout);
fclose(fpout);
delete[] yuvbuf;
delete[] dstbuf;
}
/**
* 逆时针180。
* 取元素:从右下方第一个点开始,从右往左,从下往上取点;
* 放元素:从左上方第一个位置开始放,从左往右,从上往下;
*
* @param yuvFileaName 一帧YUV420P格式的文件
* @param width 图像的宽
* @param height 图像的高
*
* @return 空
*/
void contrarotate180(const char* yuvFileaName, int width, int height){
FILE* fp = NULL;
fopen_s(&fp, yuvFileaName, "rb");
unsigned char* yuvbuf = new unsigned char[width*height * 3 / 2];
fread(yuvbuf, width*height * 3 / 2, 1, fp);
fclose(fp);
int idx = 0;
//Y
unsigned char* dstbuf = new unsigned char[width*height * 3 / 2];
for (int i = height - 1; i >= 0; i--){
for (int j = width - 1; j >= 0; j--){
dstbuf[idx++] = *(yuvbuf + (i*width + j));
}
}
//U
unsigned char* uheader = yuvbuf + width*height;
for (int i = height / 2 - 1; i >= 0; i--){
for (int j = width / 2 - 1; j >= 0; j--){
dstbuf[idx++] = *(uheader + (i*width / 2 + j));
}
}
unsigned char* vheader = uheader + width*height / 4;
//V
for (int i = height / 2 - 1; i >= 0; i--){
for (int j = width / 2 - 1; j >= 0; j--){
dstbuf[idx++] = *(vheader + (i*width / 2 + j));
}
}
FILE* fpout = NULL;
fopen_s(&fpout, "contrarotate180.yuv", "wb");
fwrite(dstbuf, width*height * 3 / 2, 1, fpout);
fclose(fpout);
delete[] yuvbuf;
delete[] dstbuf;
}
/**
* 镜像翻转/水平翻转
* 取元素:将右上角的点作为第一个点,从右往左,从上往下取点;
* 放元素:从左上方第一个位置开始放,从左往右,从上往下;
*
* @param yuvFileaName 一帧YUV420P格式的文件
* @param width 图像的宽
* @param height 图像的高
*
* @return 空
*/
void flipHorizontal(const char* yuvFileaName, int width, int height)
{
FILE* fp = NULL;
fopen_s(&fp, yuvFileaName, "rb");
unsigned char* yuvbuf = new unsigned char[width*height * 3 / 2];
fread(yuvbuf, width*height * 3 / 2, 1, fp);
fclose(fp);
int idx = 0;
//Y
unsigned char* dstbuf = new unsigned char[width*height * 3 / 2];
for (int i = 0; i < height; i++){
for (int j = width - 1; j >= 0; j--){
dstbuf[idx++] = *(yuvbuf + (i*width + j));
}
}
//U
unsigned char* uheader = yuvbuf + width*height;
for (int i = 0; i < height / 2; i++){
for (int j = width / 2 - 1; j >= 0; j--){
dstbuf[idx++] = *(uheader + (i*width / 2 + j));
}
}
//V
unsigned char* vheader = uheader + width*height / 4;
for (int i = 0; i < height / 2; i++){
for (int j = width / 2 - 1; j >= 0; j--){
dstbuf[idx++] = *(vheader + (i*width / 2 + j));
}
}
FILE* fpout = NULL;
fopen_s(&fpout, "flipHorizontal.yuv", "wb");
fwrite(dstbuf, width*height * 3 / 2, 1, fpout);
fclose(fpout);
delete[] yuvbuf;
delete[] dstbuf;
}
/**
* 逆时针旋转180后,再水平翻转/镜像。
* 取元素:从左下方第一个点开始,从左往右,从下往上取点;
* 放元素:从左上方第一个位置开始放,从左往右,从上往下;
*
* @param yuvFileaName 一帧YUV420P格式的文件
* @param width 图像的宽
* @param height 图像的高
*
* @return 空
*/
void contrarotate180AndFlipHorizontal(const char* yuvFileaName, int width, int height){
FILE* fp = NULL;
fopen_s(&fp, yuvFileaName, "rb");
unsigned char* yuvbuf = new unsigned char[width*height * 3 / 2];
fread(yuvbuf, width*height * 3 / 2, 1, fp);
fclose(fp);
int idx = 0;
//Y 宽
unsigned char* dstbuf = new unsigned char[width*height * 3 / 2];
for (int i = height - 1; i >= 0; i--){
for (int j = 0; j <= width - 1; j++){
dstbuf[idx++] = *(yuvbuf + (i*width + j));
}
}
//U
unsigned char* uheader = yuvbuf + width*height;
for (int i = height / 2 - 1; i >= 0; i--){
for (int j = 0; j <= width / 2 - 1; j++){
dstbuf[idx++] = *(uheader + (i*width / 2 + j));
}
}
//V
unsigned char* vheader = uheader + width*height / 4;
for (int i = height / 2 - 1; i >= 0; i--){
for (int j = 0; j <= width / 2 - 1; j++){
dstbuf[idx++] = *(vheader + (i*width / 2 + j));
}
}
FILE* fpout = NULL;
fopen_s(&fpout, "contrarotate180AndFlipHorizontal.yuv", "wb");
fwrite(dstbuf, width*height * 3 / 2, 1, fpout);
fclose(fpout);
delete[] yuvbuf;
delete[] dstbuf;
}
int _tmain(int argc, _TCHAR* argv[])
{
const char* yuvFileaName = "yuv420p.yuv";
int w = 160;
int h = 128;
clockwiseRotate90(yuvFileaName, w, h);
contrarotate90(yuvFileaName, w, h);
contrarotate180(yuvFileaName, w, h);
flipHorizontal(yuvFileaName, w, h);
contrarotate180AndFlipHorizontal(yuvFileaName, w, h);
return 0;
}
来源:CSDN
作者:huangjiazhi_
链接:https://blog.csdn.net/huangjiazhi_/article/details/103960883