/***
* 本程序读取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;
}