opencv:将Scalar转换为float或double类型

时间:2012-06-17 13:09:07

标签: c opencv scalar

任何人都可以帮我将openCV的标量类型转换为float或double等基本类型吗?

Scalar Sum1=sum(arg1),Sum2=sum(arg2);
theta.at<float>(i,j)=0.5*atan(Sum1/Sum2);

我必须对Mat对象arg1arg2(邻域和)的所有元素求和,然后我必须执行它们的除法以在每个像素处找到方向字段。我执行了总和,但由于我必须应用arctan函数,标量类型不适合。任何人都可以帮助我将标量类型转换为基本类型吗?

实际上我正在尝试应用log-gabor过滤器,到目前为止我所做的代码是:

//function to enhance fingerprint by log-gabor filter

void filter(Mat src, Mat finalImage)
{

//Sobel derivatives for orientation estimation

Mat grad_x,grad_y,grad2_x,grad2_y,fImage;
src.convertTo(fImage, CV_32F);

//1st and second order gradient

Sobel(fImage,grad_x,CV_32F,1,0,3);
Sobel(fImage,grad_y,CV_32F,0,1,3);    
Sobel(fImage,grad2_x,CV_32F,2,0,3);
Sobel(fImage,grad2_y,CV_32F,0,2,3);

//orientation estimation

Mat theta=Mat::zeros(fImage.size(),CV_32F);
Size block=Size(12,12);
copyMakeBorder(grad_x, grad_x, block.height/2, block.height/2,
               block.width/2,block.width/2 , BORDER_CONSTANT, Scalar::all(0));

copyMakeBorder(grad2_x, grad2_x, block.height/2, block.height/2,
               block.width/2,block.width/2 , BORDER_CONSTANT, Scalar::all(0));

copyMakeBorder(grad_y, grad_y, block.height/2, block.height/2,
               block.width/2,block.width/2 , BORDER_CONSTANT, Scalar::all(0));

copyMakeBorder(grad2_y, grad2_y, block.height/2, block.height/2,
               block.width/2,block.width/2 , BORDER_CONSTANT, Scalar::all(0));
Size imgSz=grad_x.size();
for(int i=block.width/2;i<imgSz.width-block.width/2;++i)
    for(int j=block.height/2;j<imgSz.height-block.height/2;++j)
    {
        Mat roi_gradX=grad_x(Range(i-block.width/2,i+block.width/2),
                             Range(j-block.width/2,j+block.width/2));

        Mat roi_gradY=grad_y(Range(i-block.width/2,i+block.width/2),
                             Range(j-block.width/2,j+block.width/2));

        Mat roi_gradX2=grad2_x(Range(i-block.width/2,i+block.width/2),
                             Range(j-block.width/2,j+block.width/2));

        Mat roi_gradY2=grad2_y(Range(i-block.width/2,i+block.width/2),
                             Range(j-block.width/2,j+block.width/2));

        Mat arg1,arg2;
        multiply(roi_gradX,roi_gradY,arg1);
        arg1*=2;
        subtract(roi_gradX2,roi_gradY2,arg2);
        Scalar Sum1=sum(arg1),Sum2=sum(arg2);

        theta.at<float>(i,j)=0.5*atan(Sum1/Sum2);
    }
}

3 个答案:

答案 0 :(得分:25)

我用

double s;
s = sum(arg1)[0];

答案 1 :(得分:3)

修改

来自OpenCV文档:

  

<强>总和
  ...
  函数sum计算并返回数组元素的总和,   每个频道独立。

Sobel生成的输出图像是具有一个通道的二进制图像,因为您需要使用Sum1Sum2标量来计算弧的主要值正切。

错误,因为应该应用Log-Gabor过滤器......

看起来你尝试做很多事情,可以由atan(Sum1[0]/Sum2[0])处理...如果你想对你的图像应用Gabor过滤器,那么看看这个,我发现{{3} }:

cv::filter2D()

答案 2 :(得分:1)

标量是从Vec派生的双元素的4元素向量,如opencv文档中所示(http://docs.opencv.org/2.4.9/modules/core/doc/basic_structures.html#scalar

如果矩阵有多个通道,函数cv :: sum将分别对每个通道中的元素求和,并将它们存储在标量Vec上。因此,要访问每个通道的双打,您必须访问向量上的位置。 (文件:http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#sum

//sum for first channel
double sum1 = cv::sum(my_mat)[0];
//sum for second channel
double sum2 = cv::sum(my_mat)[1];
//sum for third channel
double sum3 = cv::sum(my_mat)[2];