/************中心环形矢量场*马鞍矢量场*****卷积白噪声纹理***********/
#include
#include
#include
#include
#include
#include
#include
#include "netcdfcpp.h"
using namespace std;
#define SQUARE_FLOW_FIELD_SZ 400
#define DISCRETE_FILTER_SIZE 2048 //离散的滤波尺寸
#define LOWPASS_FILTR_LENGTH 10.00000f //低通滤波长度
#define LINE_SQUARE_CLIP_MAX 100000.0f //线性平方夹
#define VECTOR_COMPONENT_MIN 0.050000f //矢量分量最小值
void SyntheszSaddle(int n_xres, int n_yres, float* pVectr);
void NormalizVectrs(int n_xres, int n_yres, float* pVectr,float* vecSize);
void GenBoxFiltrLUT(int LUTsiz, float* p_LUT0, float* p_LUT1);
void MakeWhiteNoise(int n_xres, int n_yres, unsigned char* pNoise);
void FlowImagingLIC(int n_xres, int n_yres, float* pVectr, unsigned char* pNoise,
unsigned char* pImage, float* p_LUT0, float* p_LUT1, float krnlen);
void WriteImage2PPM(int n_xres, int n_yres, unsigned char* pImage,char* f_name);
void color(int n_xres, int n_yres,unsigned char *pImage,float* vecSize);
double maxvecmag;
void main()
{
// int n_xres = 721;
// int n_yres = 281;
int n_xres = 1441;
int n_yres = 561;
// int n_xres = 2881;
// int n_yres = 1121;
//
// int n_xres = 5761;
// int n_yres = 2241;
// int n_xres = 11521;
// int n_yres = 2241;
float* pVectr = (float* ) malloc( sizeof(float ) * n_xres * n_yres * 2 );
float* p_LUT0 = (float* ) malloc( sizeof(float ) * DISCRETE_FILTER_SIZE);
float* p_LUT1 = (float* ) malloc( sizeof(float ) * DISCRETE_FILTER_SIZE);
unsigned char* pNoise = (unsigned char* ) malloc( sizeof(unsigned char) * n_xres * n_yres );
unsigned char* pImage = (unsigned char* ) malloc( sizeof(unsigned char) * n_xres * n_yres );
float* vecSize = (float* ) malloc( sizeof(float) * n_xres*n_yres );
SyntheszSaddle( n_xres, n_yres, pVectr);
//CenterFiled(n_xres, n_yres, pVectr);//包含矢量归一化
NormalizVectrs(n_xres, n_yres, pVectr,vecSize);//所以这就不用矢量归一化了,因为之前的马鞍矢量场生成函数里没有归一化,才有此步的
MakeWhiteNoise(n_xres, n_yres, pNoise);
GenBoxFiltrLUT(DISCRETE_FILTER_SIZE, p_LUT0, p_LUT1);
FlowImagingLIC(n_xres, n_yres, pVectr, pNoise, pImage, p_LUT0, p_LUT1, LOWPASS_FILTR_LENGTH);
// color(n_xres, n_yres,pImage,vecSize);
//WriteImage2PPM(n_xres, n_yres, pImage, "LIC.ppm");
// WriteImage2PPM(n_xres, n_yres, pImage, "LIC_721_281.ppm");
WriteImage2PPM(n_xres, n_yres, pImage, "LIC1441_561.ppm");
// WriteImage2PPM(n_xres, n_yres, pImage, "LIC2281_1121.ppm");
//WriteImage2PPM(n_xres, n_yres, pImage, "LIC5761_1121.ppm");
//WriteImage2PPM(n_xres, n_yres, pImage, "LIC_11521_2241.ppm");
//system("pause");
free(pVectr); pVectr = NULL;
free(p_LUT0); p_LUT0 = NULL;
free(p_LUT1); p_LUT1 = NULL;
free(pNoise); pNoise = NULL;
free(pImage); pImage = NULL;
}
/// 中心环形矢量场图形 synthesize a saddle-shaped vector field ///
void SyntheszSaddle(int n_xres, int n_yres, float* pVectr)
{
static const int LatNum = n_yres;
static const int LonNum = n_xres;
static const int Time = 1;
static const int TMP = Time*LonNum*LatNum;
//NcFile dataReadFile("global_721_281.nc",NcFile::ReadOnly);
NcFile dataReadFile("global_1441_561.nc",NcFile::ReadOnly);
// NcFile dataReadFile("global_2881_1121.nc",NcFile::ReadOnly);
// NcFile dataReadFile("global_5761_2241.nc",NcFile::ReadOnly);
//NcFile dataReadFile("global_11521_2241.nc",NcFile::ReadOnly);
if (!dataReadFile.is_valid())
{
std::cout<<"couldn't open file!"<get(Tmp_LAT,LatNum,LatNum);
dataTmp_LON->get(Tmp_LON,LonNum,LonNum);
dataTmp_UX->get(Tmp_UX,Time,LatNum,LonNum);
dataTmp_VY->get(Tmp_VY,Time,LatNum,LonNum);
for(int j = 0; j < n_yres; j ++)
for(int i = 0; i < n_xres; i ++)
{
int index = ( (n_yres - 1 - j) * n_xres + i ) << 1;
//int index = j*n_yres+i;
pVectr[index ] = Tmp_UX[j*LonNum+i];
pVectr[index +1 ]= Tmp_VY[j*LonNum+i];
}
delete []Tmp_UX;
delete []Tmp_VY;
delete []Tmp_LAT;
}
/// normalize the vector field ///
// void NormalizVectrs(int n_xres, int n_yres, float* pVectr)
// {
//
//
// for(int j = 0; j < n_yres; j ++)
// for(int i = 0; i < n_xres; i ++)
// {
// int index = (j * n_xres + i) << 1;
// float vcMag = float( sqrt( double(pVectr[index] * pVectr[index] + pVectr[index + 1] * pVectr[index + 1]) ) );
//
// float scale = (vcMag == 0.0f) ? 0.0f : 1.0f / vcMag;//矢量大小归一化后的矢量值
// //pVectr[index ] *= scale;
// pVectr[index ]=pVectr[index ]*scale;
// // cout<<"pVectr[index ]="<maxvecmag)
{
maxvecmag=vcMag;
}
float scale = (vcMag == 0.0f) ? 0.0f : 1.0f / vcMag;
pVectr[index ] *= scale*5.5;//????????????????????????????????????????????????????????????原来问题出在这
pVectr[index + 1] *= scale*5.5;
}
}
/// make white noise as the LIC input texture ///
// void MakeWhiteNoise(int n_xres, int n_yres, unsigned char* pNoise)
// {
// IplImage * NoiseImg=cvCreateImage(cvSize(n_xres,n_yres),IPL_DEPTH_8U,1);
// CvScalar s;
//
// for(int j = 0; j < n_yres; j ++)
// {
// for(int i = 0; i < n_xres; i ++)
//
// // for(int j = 0; j < n_yres; j=j +10)//产生稀疏白噪声
// // {
// // for(int i = 0; i < n_xres; i=i+10)
//
// {
// int r = rand();
// r = ( (r & 0xff) + ( (r & 0xff00) >> 8 ) ) & 0xff;
// pNoise[j * n_xres + i] = (unsigned char) r;
// s = cvGet2D(NoiseImg,i,j);
// s.val[0]=r;
// s.val[1]=r;
// s.val[2]=r;
// cvSet2D(NoiseImg,i,j,s);
// }
// }
//
// }
void MakeWhiteNoise(int n_xres, int n_yres, unsigned char* pNoise)
{
for(int j = 0; j < n_yres; j ++)
for(int i = 0; i < n_xres; i ++)
{
int r = rand();
r = ( (r & 0xff) + ( (r & 0xff00) >> 8 ) ) & 0xff;
pNoise[j * n_xres + i] = (unsigned char) r;
}
}
/// generate box filter LUTs ///
void GenBoxFiltrLUT(int LUTsiz, float* p_LUT0, float* p_LUT1)
{
for(int i = 0; i < LUTsiz; i ++) p_LUT0[i] = p_LUT1[i] = i;
}
void color(int n_xres,int n_yres, unsigned char* pImage,float* vecSize)
{
IplImage * licImage = cvCreateImage(cvSize(n_xres,n_yres),IPL_DEPTH_8U,3);
IplImage* img = cvLoadImage("11.jpg",1);
int k = 0;
double magind;
double mag;
double newMag;
double x = 0.1;//x为非线性映射因子,且x!=1
CvScalar colorTable[500];
CvScalar s,s1;
for (int i = 0;i < img->width;i++)
{
s = cvGet2D(img,1,i);
colorTable[i] =s;
}
for (int j=0;j=img->width)
{
k=0;
}
double scale= pImage[j * n_xres + i];
mag = vecSize[j * n_xres + i];
//********矢量大小归一化******
if (mag<100)
{
magind = (mag/maxvecmag);
}
//非线性颜色增强LIC
newMag =(pow(x,magind)-1)/(x-1);
s = cvGet2D(licImage,j,i);
//渐变颜色映射表
int k = int(newMag*446);
s1.val[0]=colorTable[k].val[0]*(k+1-newMag*446)+colorTable[k+1].val[0]*(newMag*446-k);
s1.val[1]=colorTable[k].val[1]*(k+1-newMag*446)+colorTable[k+1].val[1]*(newMag*446-k);
s1.val[2]=colorTable[k].val[2]*(k+1-newMag*446)+colorTable[k+1].val[2]*(newMag*446-k);
s1.val[0]*=scale;
s1.val[1]*=scale;
s1.val[2]*=scale;
/*cout<<"s1.val[3]="< VECTOR_COMPONENT_MIN) ? ( int( int(clp0_x) + 1.5f ) - clp0_x ) / vctr_x : segLen;
segLen = (vctr_y < -VECTOR_COMPONENT_MIN) ?
( ( ( tmpLen = ( int( clp0_y) - clp0_y ) / vctr_y ) < segLen ) ? tmpLen : segLen )
: segLen;
segLen = (vctr_y > VECTOR_COMPONENT_MIN) ?
( ( ( tmpLen = ( int( int(clp0_y) + 1.5f ) - clp0_y ) / vctr_y ) < segLen ) ? tmpLen : segLen )
: segLen;
///update the curve-length measurers///
prvLen = curLen;
curLen+= segLen;
segLen+= 0.0004f;
///check if the filter has reached either end///
segLen = (curLen > krnlen) ? ( (curLen = krnlen) - prvLen ) : segLen;
///obtain the next clip point///
clp1_x = clp0_x + vctr_x * segLen;
clp1_y = clp0_y + vctr_y * segLen;
///obtain the middle point of the segment as the texture-contributing sample///
samp_x = (clp0_x + clp1_x) * 0.5f;
samp_y = (clp0_y + clp1_y) * 0.5f;
///obtain the texture value of the sample///
texVal = pNoise[ int(samp_y) * n_xres + int(samp_x) ];
///update the accumulated weight and the accumulated composite texture (texture x weight)///
W_ACUM = wgtLUT[ int(curLen * len2ID) ];
smpWgt = W_ACUM - w_acum[advDir];
w_acum[advDir] = W_ACUM;
t_acum[advDir] += texVal * smpWgt;
///update the step counter and the "current" clip point///
advcts ++;
clp0_x = clp1_x;
clp0_y = clp1_y;
///check if the streamline has gone beyond the flow field///
if( clp0_x < 0.0f || clp0_x >= n_xres || clp0_y < 0.0f || clp0_y >= n_yres) break;
}
}
///normalize the accumulated composite texture///
texVal = (t_acum[0] + t_acum[1]) / (w_acum[0] + w_acum[1]);
///clamp the texture value against the displayable intensity range [0, 255]
texVal = (texVal < 0.0f) ? 0.0f : texVal;
texVal = (texVal > 255.0f) ? 255.0f : texVal;
pImage[j * n_xres + i] = (unsigned char) texVal;
}
}