Пример #1
0
gmMatrix3 Algebraic::hess(const gmVector3 & v)
{
    double dfdxy = dxdy(v), dfdxz = dxdz(v), dfdyz = dydz(v);
    double dfdxx = dx2(v),  dfdyy = dy2(v),  dfdzz = dz2(v);

    gmMatrix3 hess(dfdxx,   dfdxy,  dfdxz,
                   dfdxy,   dfdyy,  dfdyz,
                   dfdxz,   dfdyz,  dfdzz);
    return hess;
}
Пример #2
0
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Tensor::Tensor(const IplImage *cv_image, BOOL isComputeGradient)
{
	//保存原图像的副本
	m_img=cvCreateImage(cvSize(cv_image->width,cv_image->height),cv_image->depth,3);
	cvCopyImage(cv_image,m_img);

	//获取非线性多尺度结构张量的参数值
	m_levels = 2;

	ASSERT(m_levels > 0 );

	m_dim = m_levels * SiNGLE_TENSOR_DIM;    //SiNGLE_TENSOR_DIM单一张量

	//SiNGLE_TENSOR_DIM=n(n+1)/2;反解n=m_axes_cnt,m_axes_cnt为坐标抽的维数
	m_axes_cnt = (unsigned int)(sqrt(2 * SiNGLE_TENSOR_DIM + 0.25) - 0.5);   // 2

	m_grad_dim = m_levels * m_axes_cnt;      //m_grad_dim


	////////////////////////////////////////////////////////////////////////////
	//将多通道转化为单通道,默认为三个通道
	unsigned int x,y,i,n;
	m_w = cv_image->width;
	m_h = cv_image->height;
	IplImage *cv_channels[3];
	for (n = 0;n < 3;n++)
	{
		cv_channels[n] = cvCreateImage( cvGetSize(cv_image), cv_image->depth, 1 );
	}
	cvSplit(cv_image, cv_channels[0], cv_channels[1], cv_channels[2], NULL);


	////////////////////////////////////////////////////////////////////////////
	//初始化m_tensor,CMatrix(m_h,m_w)创建一个矩阵,其元素全为0
	m_tensor = new CMatrix *[m_dim];
	for (i=0;i<m_dim;i++)
	{   
		m_tensor[i] = new CMatrix(m_h,m_w);
	}

	////////////////////////////////////////////////////////////////////////////
	//将每一尺度的张量转化为彩色图像存储起来,申请空间	
	m_pImageTensorRGB=new Image<Color_RGB> *[m_levels];
	for (i=0;i<m_levels;i++)
	{   
		m_pImageTensorRGB[i] = new Image<Color_RGB> (m_w,m_h);
	}

	//初始化m_gradient
	if (isComputeGradient)
	{
		m_gradient = new CMatrix *[m_grad_dim];
		for (i=0;i<m_grad_dim;i++)
		{
			m_gradient[i] = new CMatrix(m_h,m_w);
		}
	}
	else
	{
		m_gradient = NULL;
	}


	//辅助矩阵
	CMatrix image(m_h, m_w);
	CMatrix dx(m_h,m_w);
	CMatrix dy(m_h,m_w);
	CMatrix dx2(m_h,m_w);
	CMatrix dy2(m_h,m_w);
	CMatrix dxdy(m_h,m_w);

	//利用固定数据创建一个矩阵
	CvMat cv_dx2 = cvMat(m_h, m_w, CV_64FC1, dx2.GetData());
	CvMat cv_dy2 = cvMat(m_h, m_w, CV_64FC1, dy2.GetData());
	CvMat cv_dxdy =cvMat(m_h, m_w, CV_64FC1, dxdy.GetData());


	//完成IplImage向CMatrix类型的转换,对每一个颜色通道分别进行处理
	for (n = 0;n <3;n++)	//n表示通道数,默认为3
	{  
		//将每一个通道的元素拷贝到image中
		for (y = 0; y < m_h; y++)
		{
			for (x = 0; x < m_w; x++)
			{
				uchar* dst = &CV_IMAGE_ELEM( cv_channels[n], uchar, y, x );
				image.SetElement(y, x, (double)(dst[0]));
			}
		}
		//计算每一个颜色通道的梯度(x方向,y方向)并分别赋给dx,dy
		image.centdiffX(dx);
		image.centdiffY(dy);

		//将dx,dy分别赋给cv_dx,cv_dy
		CvMat cv_dx = cvMat(m_h, m_w, CV_64FC1, dx.GetData());
		CvMat cv_dy = cvMat(m_h, m_w, CV_64FC1, dy.GetData());

		//初始化cv_tensor0,cv_tensor1,cv_tensor2,此时m_tensor[0],m_tensor[1],m_tensor[2]均初始化0
		CvMat cv_tensor0 = cvMat(m_h, m_w, CV_64FC1, (m_tensor[0])->GetData());
		CvMat cv_tensor1 = cvMat(m_h, m_w, CV_64FC1, (m_tensor[1])->GetData());
		CvMat cv_tensor2 = cvMat(m_h, m_w, CV_64FC1, (m_tensor[2])->GetData());

		//计算图像的梯度,保存在cv_gradX,cv_gradY中,并赋值给m_gradient[0],m_gradient[1]
		if (isComputeGradient)
		{   
			//cv_gradX,cv_gradY初始化并计算
			CvMat cv_gradX = cvMat(m_h, m_w, CV_64FC1, (m_gradient[0])->GetData());
			CvMat cv_gradY = cvMat(m_h, m_w, CV_64FC1, (m_gradient[1])->GetData());
			cvAdd(&cv_gradX, &cv_dx, &cv_gradX);//对于三个通道进行累加
			cvAdd(&cv_gradY, &cv_dy, &cv_gradY);
		}

		//计算结构张量,cv_tensor0=dx*dx,cv_tensor1=dy*dy,cv_tensor2=dx*dy
		cvMul(&cv_dx, &cv_dx, &cv_dx2);
		cvAdd(&cv_tensor0, &cv_dx2, &cv_tensor0);
		cvMul(&cv_dy, &cv_dy, &cv_dy2);
		cvAdd(&cv_tensor1, &cv_dy2, &cv_tensor1);
		cvMul(&cv_dx, &cv_dy, &cv_dxdy);
		cvAdd(&cv_tensor2, &cv_dxdy, &cv_tensor2);


		//单尺度计算完毕,以下为多尺度非线性结构张量的计算方法
		if (m_levels > 1)
		{   
			unsigned int wavelet_levels = m_levels - 1;	//-1的原因是因为之前没有if (m_levels==1)的判断语句	
			double dMaxValue,dMinValue;
			cvMinMaxLoc(cv_channels[n], &dMinValue, &dMaxValue);//Finds global minimum, maximum 

			//将图像的像素值归一化到[0,1]
			Wavelet *wave = new Wavelet(&image, dMinValue, dMaxValue, wavelet_levels); //调用Wavelet的构造函数

			//新建WaveletDetailImages结构体的数组
			WaveletDetailImages *D_images = new WaveletDetailImages[wavelet_levels];

			for (i = 0; i < wavelet_levels; i++)
			{
				D_images[i].Detail_1 = new CMatrix(m_h, m_w);
				D_images[i].Detail_2 = new CMatrix(m_h, m_w);
			}

			wave->execute(D_images);//得到D(s,x),D(s,y)

			for (i = 0; i < wavelet_levels; i++)
			{   
				//默认多尺度结构张量的比例因子a=2
				double scale = pow((float)0.25, (int)(i + 1));              //见公式(2-15)
				CvMat cv_dx = cvMat(m_h, m_w, CV_64FC1, D_images[i].Detail_1->GetData());
				CvMat cv_dy = cvMat(m_h, m_w, CV_64FC1, D_images[i].Detail_2->GetData());
				CvMat cv_tensor0 = cvMat(m_h, m_w, CV_64FC1, (m_tensor[(i+1) * SiNGLE_TENSOR_DIM])->GetData());
				CvMat cv_tensor1 = cvMat(m_h, m_w, CV_64FC1, (m_tensor[(i+1) * SiNGLE_TENSOR_DIM + 1])->GetData());
				CvMat cv_tensor2 = cvMat(m_h, m_w, CV_64FC1, (m_tensor[(i+1) * SiNGLE_TENSOR_DIM + 2])->GetData());
				//计算梯度
				if (isComputeGradient)
				{
					CvMat cv_gradX = cvMat(m_h, m_w, CV_64FC1, (m_gradient[(i+1) * m_axes_cnt])->GetData());
					CvMat cv_gradY = cvMat(m_h, m_w, CV_64FC1, (m_gradient[(i+1) * m_axes_cnt + 1])->GetData());
					cvAdd(&cv_gradX, &cv_dx, &cv_gradX);
					cvAdd(&cv_gradY, &cv_dy, &cv_gradY);
				}
				//计算张量
				cvMul(&cv_dx, &cv_dx, &cv_dx2, scale);
				cvAdd(&cv_tensor0, &cv_dx2, &cv_tensor0);
				cvMul(&cv_dy, &cv_dy, &cv_dy2, scale);
				cvAdd(&cv_tensor1, &cv_dy2, &cv_tensor1);
				cvMul(&cv_dx, &cv_dy, &cv_dxdy, scale);
				cvAdd(&cv_tensor2, &cv_dxdy, &cv_tensor2);
			}
			for (i = 0; i < wavelet_levels; i++)
			{
				delete D_images[i].Detail_1;
				delete D_images[i].Detail_2;
			}
			delete [] D_images;
			delete wave;
		}
		cvReleaseImage(&cv_channels[n]);
	}

	//将每一尺度的结构张量转换为彩色图像存储起来
	for (i=0;i<m_levels;i++)
	{
		for (y=0;y<m_h;y++)
		{
			for (x=0;x<m_w;x++)
			{
				(*m_pImageTensorRGB[i])(x,y).r=(m_tensor[i*SiNGLE_TENSOR_DIM])->GetElement(y,x);
				(*m_pImageTensorRGB[i])(x,y).g=(m_tensor[i*SiNGLE_TENSOR_DIM+1])->GetElement(y,x);
				(*m_pImageTensorRGB[i])(x,y).b=(m_tensor[i*SiNGLE_TENSOR_DIM+2])->GetElement(y,x);
			}
		}
	}
	m_tensors = NULL;	
}