读取yuv数据并做光流法处理

该程序详细说明了如何从YUV格式的数据开始,通过cv::cvtColor转换为OpenCV兼容的Mat格式,进而进行光流法处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/***

* 本程序读取yuv数据,调用 cv::cvtColor(yuvImg, frame, cv_YUV2BGR_I420)

* 将yuv数据转化为Opencv能够读取的 Mat 格式数据,然后做光流法处理

*/






#include <windows.h>  
#include <iostream>  
#include <opencv/cv.h>
#include <fstream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include "PA.h"
#include "GF_Feature.h";

#include <opencv2/opencv.hpp>  

using namespace cv;  
using namespace std;  

#define UNKNOWN_FLOW_THRESH 1e9  

void makecolorwheel(vector<Scalar> &colorwheel)  
{  
	int RY = 15;  
	int YG = 6;  
	int GC = 4;  
	int CB = 11;  
	int BM = 13;  
	int MR = 6;  

	int i;  

	for (i = 0; i < RY; i++) colorwheel.push_back(Scalar(255,       255*i/RY,     0));  
	for (i = 0; i < YG; i++) colorwheel.push_back(Scalar(255-255*i/YG, 255,       0));  
	for (i = 0; i < GC; i++) colorwheel.push_back(Scalar(0,         255,      255*i/GC));  
	for (i = 0; i < CB; i++) colorwheel.push_back(Scalar(0,         255-255*i/CB, 255));  
	for (i = 0; i < BM; i++) colorwheel.push_back(Scalar(255*i/BM,      0,        255));  
	for (i = 0; i < MR; i++) colorwheel.push_back(Scalar(255,       0,        255-255*i/MR));  
}  

void motionToColor(Mat flow, Mat &color)  
{  
	if (color.empty())  
		color.create(flow.rows, flow.cols, CV_8UC3);  

	static vector<Scalar> colorwheel; //Scalar r,g,b  
	if (colorwheel.empty())  
		makecolorwheel(colorwheel);  

	// determine motion range:  
	float maxrad = -1;  

	// Find max flow to normalize fx and fy  
	for (int i= 0; i < flow.rows; ++i)   
	{  
		for (int j = 0; j < flow.cols; ++j)   
		{  
			Vec2f flow_at_point = flow.at<Vec2f>(i, j);  
			float fx = flow_at_point[0];  
			float fy = flow_at_point[1];  
			if ((fabs(fx) >  UNKNOWN_FLOW_THRESH) || (fabs(fy) >  UNKNOWN_FLOW_THRESH))  
				continue;  
			float rad = sqrt(fx * fx + fy * fy);  
			maxrad = maxrad > rad ? maxrad : rad;  
		}  
	}  



	for (int i= 0; i < flow.rows; ++i)   
	{  
		for (int j = 0; j < flow.cols; ++j)   
		{  
			uchar *data = color.data + color.step[0] * i + color.step[1] * j;  
			Vec2f flow_at_point = flow.at<Vec2f>(i, j);  

			float fx = flow_at_point[0] / maxrad;  
			float fy = flow_at_point[1] / maxrad;  
			if ((fabs(fx) >  UNKNOWN_FLOW_THRESH) || (fabs(fy) >  UNKNOWN_FLOW_THRESH))  
			{  
				data[0] = data[1] = data[2] = 0;  
				continue;  
			}  
			float rad = sqrt(fx * fx + fy * fy);  

			float angle = atan2(-fy, -fx) / CV_PI;  
			float fk = (angle + 1.0) / 2.0 * (colorwheel.size()-1);  
			int k0 = (int)fk;  
			int k1 = (k0 + 1) % colorwheel.size();  
			float f = fk - k0;  
			//f = 0; // uncomment to see original color wheel  

			for (int b = 0; b < 3; b++)   
			{  
				float col0 = colorwheel[k0][b] / 255.0;  
				float col1 = colorwheel[k1][b] / 255.0;  
				float col = (1 - f) * col0 + f * col1;  
				if (rad <= 1)  
					col = 1 - rad * (1 - col); // increase saturation with radius  
				else  
					col *= .75; // out of range  
				data[2 - b] = (int)(255.0 * col);  
			}  
		}  
	}  
}  


const int width = 1280;
const int height = 720;
const int framesize = width * height * 3/2;


int main(int, char**)  
{ 	
	ifstream fin;
	fin.open("demo.yuv", ios_base::in | ios_base::binary);
	if (fin.fail()) {
		cout << "this file is error!\n";
		return -1;
	}
	fin.seekg(0, ios::end);
	streampos ps = fin.tellg();
	unsigned long NumberPixel = ps;
	cout << "file size:" << ps << endl;
	unsigned FrameCount = ps / framesize;
	cout << "frameNumber: " << FrameCount;
	fin.close();



	Mat prevgrayImage, grayImage, flow , frame, cflow; //cflow
	Mat motion2color;  

	
	FILE* fileIn = fopen("demo.yuv", "rb+");
	unsigned char* pYuvBuf = new unsigned char[framesize];
	namedWindow("孟塞尔颜色", 1); 
	//namedWindow("光流", 1);

	int i;
	for(i=0; i<FrameCount; i++)  
	{   
		//fread(pYuvBuf, framesize*sizeof(unsigned char), 1, fileIn);
		//cv::Mat yuvImg;
		//yuvImg.create(height*3/2, width, CV_8UC1);

		fread(pYuvBuf, framesize*sizeof(unsigned char), 1, fileIn);
		cv::Mat yuvImg;
		yuvImg.create(height*3/2, width, CV_8UC1);
		memcpy(yuvImg.data, pYuvBuf, framesize*sizeof(unsigned char));
		cv::cvtColor(yuvImg, frame, CV_YUV2BGR_I420); // YUV转rgb
		cv::imshow("rgbImg", frame);

		double t = (double)cvGetTickCount();  
//		cap >> frame;
		//		imshow("源图像", frame); //6-24
		cvtColor(frame, grayImage, CV_BGR2GRAY);
		//		imshow("灰度图像", grayImage);
		if( prevgrayImage.data )  
		{  
			calcOpticalFlowFarneback(prevgrayImage, grayImage, flow, 0.5, 3, 15, 3, 5, 1.2,0);  

			int fwidth = flow.cols;
			int fheight = flow.rows;

			//主机端的光流图像数据
			VECT2F * h_MatData;
			h_MatData = (VECT2F *)malloc(fwidth*fheight*sizeof(GradientDirection));
			memset(h_MatData,0,fwidth*fheight*sizeof(VECT2F));

			memcpy(h_MatData,flow.data,fwidth*fheight*sizeof(VECT2F));

			//运动方向熵
			float h_Entropy;
			computeFeature(h_MatData, &h_Entropy,fwidth,fheight);
			printf("熵:%f \n",h_Entropy);

			//Sleep(1111);
			//开始由灰度共生矩阵计算出图像特征

			//主机端8维的特征向量
			float h_featureVector[8];

			int gwidth = grayImage.cols;
			int gheight = grayImage.rows;

			//主机端灰度图像数据
			unsigned char * h_GrayData;

			h_GrayData = (unsigned char *)malloc(gwidth*gheight*sizeof(unsigned char));
			memset(h_GrayData,0,gwidth*gheight*sizeof(unsigned char));

			memcpy(h_GrayData,grayImage.data,gwidth*gheight*sizeof(unsigned char));

			computeMatrixFeature(h_GrayData,h_featureVector,gwidth,gheight);

			for(int i=0;i<8;i++)
			{
				printf("%f\t",h_featureVector[i]);
			}

			printf("\n");
			motionToColor(flow, motion2color);  
			imshow("孟塞尔颜色", motion2color);  
			//free(h_MatData);
			free(h_GrayData);
		}  

		if(waitKey(10)>=0)  
			break;  

		std::swap(prevgrayImage, grayImage);  

		t = (double)cvGetTickCount() - t;  

		cout << "cost time: " << t / ((double)cvGetTickFrequency()*1000.) << endl;  
	}  

	fclose(fileIn);
	return 0;  
}  


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值