resize_NV21

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <sstream>
#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>


using namespace cv;
using namespace std;
 
const unsigned char *BGR2NV21(cv::Mat bgrImg)
{
	int cols = bgrImg.cols;
	int rows = bgrImg.rows;
    cout<<"cols = "<< cols <<"\t ,rows = "<< rows <<endl;
 
	int Yindex = 0;
	int UVindex = rows * cols;
 
	unsigned char* yuvbuff = new unsigned char[rows * cols *3 /2];
 
	cv::Mat NV21(rows+rows/2, cols, CV_8UC1);
	
	int UVRow{ 0 };
	for (int i=0;i<rows;i++)
	{
		for (int j=0;j<cols;j++)
		{
			uchar* YPointer = NV21.ptr<uchar>(i);
 
			int B = bgrImg.at<cv::Vec3b>(i, j)[0];
			int G = bgrImg.at<cv::Vec3b>(i, j)[1];
			int R = bgrImg.at<cv::Vec3b>(i, j)[2];
 
			//计算Y的值
			int Y = (77 * R + 150 * G + 29 * B) >> 8;
			YPointer[j] = Y;
			yuvbuff[Yindex++] = (Y < 0) ? 0 : ((Y > 255) ? 255 : Y);
			uchar* UVPointer = NV21.ptr<uchar>(rows+i/2);
			//计算U、V的值,进行2x2的采样
			if (i%2==0&&(j)%2==0)
			{
				int U = ((-44 * R - 87 * G + 131 * B) >> 8) + 128;
				int V = ((131 * R - 110 * G - 21 * B) >> 8) + 128;
				UVPointer[j] = V;
				UVPointer[j+1] = U;
				yuvbuff[UVindex++] = (V < 0) ? 0 : ((V > 255) ? 255 : V);
				yuvbuff[UVindex++] = (U < 0) ? 0 : ((U > 255) ? 255 : U);
			}
		}
	}
    return yuvbuff;
}
 
const unsigned char *resize_nv21(const unsigned char *in_data , int in_w, int in_h, int out_w, int out_h)
{
    Mat nv21(in_h *3 /2, in_w, CV_8UC1,const_cast<uchar *>(in_data));//  in_data to Mat nv21

    Mat bgr;
    Mat bgr_small;//define a mat in rgb datas
    cvtColor(nv21,bgr,CV_YUV2BGR_NV21);//converto nv21 to bgr 
    resize(bgr, bgr_small, Size(out_w,out_h));
	//cv::imwrite("bgr_small.jpg", bgr_small);
    return BGR2NV21(bgr_small);
}

//使用时修改相关路径及宽高尺寸
int main()
{
	const char *filename = "yuv.yuv";  //储存原有的nv21数据
	FILE  *fp = fopen(filename,"rb");
	if(fp == nullptr){
    cout << "open file foreman failed" << endl;
    return 0;
	}

	int len = 416 * 416 * 3/2;
	const unsigned char *buff = (const unsigned char *)malloc(len);
	fread(const_cast<uchar *>(buff), sizeof(const unsigned char), len, fp);

	const char *outname = "yuv224.yuv";  //储存新生成的nv21数据
	FILE  *out = fopen(outname,"wb");
	int len_out = 224 * 224 * 3/2;
	const unsigned char *buff_out = (const unsigned char *)malloc(len_out);
	buff_out = resize_nv21(buff,416,416,224,224);

	fwrite(buff_out, sizeof(const unsigned char), len_out, out);

	return 0;
}

部分内容参考博客

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值