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

bis*_*nga 14 c scalar opencv

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

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

我必须对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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Bob*_*ett 26

我用

double s;
s = sum(arg1)[0];
Run Code Online (Sandbox Code Playgroud)


dom*_*dom 3

编辑

\n\n

来自 OpenCV 文档:

\n\n
\n

sum
\n ...
\n 函数 sum 计算并返回数组元素的总和,\n 对于每个通道都是独立的。

\n
\n\n

Sobel 生成的输出图像是具有一个通道的二值图像,因为您需要使用您的Sum1和标量来计算反正切的主值。Sum2atan(Sum1[0]/Sum2[0])

\n\n

错误,应应用 Log-Gabor 过滤器 \xe2\x80\xa6

\n\n

看起来你尝试做很多事情,可以通过cv::filter2D()\xe2\x80\xa6 处理如果你想对你的图像应用 Gabor 过滤器,那么看看我在这里找到的:

\n\n
#include <opencv2/core/core.hpp>\n#include <opencv2/imgproc/imgproc.hpp>\n#include <opencv2/highgui/highgui.hpp>\n#include <math.h>\n\ncv::Mat mkKernel(int ks, double sig, double th, double lm, double ps)\n{\n    int hks = (ks-1)/2;\n    double theta = th*CV_PI/180;\n    double psi = ps*CV_PI/180;\n    double del = 2.0/(ks-1);\n    double lmbd = lm;\n    double sigma = sig/ks;\n    double x_theta;\n    double y_theta;\n    cv::Mat kernel(ks,ks, CV_32F);\n    for (int y=-hks; y<=hks; y++)\n    {\n        for (int x=-hks; x<=hks; x++)\n        {\n            x_theta = x*del*cos(theta)+y*del*sin(theta);\n            y_theta = -x*del*sin(theta)+y*del*cos(theta);\n            kernel.at<float>(hks+y,hks+x) = (float)exp(-0.5*(pow(x_theta,2)+pow(y_theta,2))/pow(sigma,2))* cos(2*CV_PI*x_theta/lmbd + psi);\n        }\n    }\n    return kernel;\n}\n\nint kernel_size=21;\nint pos_sigma= 5;\nint pos_lm = 50;\nint pos_th = 0;\nint pos_psi = 90;\ncv::Mat src_f;\ncv::Mat dest;\n\nvoid Process(int , void *)\n{\n    double sig = pos_sigma;\n    double lm = 0.5+pos_lm/100.0;\n    double th = pos_th;\n    double ps = pos_psi;\n    cv::Mat kernel = mkKernel(kernel_size, sig, th, lm, ps);\n    cv::filter2D(src_f, dest, CV_32F, kernel);\n    cv::imshow("Process window", dest);\n    cv::Mat Lkernel(kernel_size*20, kernel_size*20, CV_32F);\n    cv::resize(kernel, Lkernel, Lkernel.size());\n    Lkernel /= 2.;\n    Lkernel += 0.5;\n    cv::imshow("Kernel", Lkernel);\n    cv::Mat mag;\n    cv::pow(dest, 2.0, mag);\n    cv::imshow("Mag", mag);\n}\n\nint main(int argc, char** argv)\n{\n    cv::Mat image = cv::imread("cat.jpg",1);\n    cv::imshow("Src", image);\n    cv::Mat src;\n    cv::cvtColor(image, src, CV_BGR2GRAY);\n    src.convertTo(src_f, CV_32F, 1.0/255, 0);\n    if (!kernel_size%2)\n    {\n        kernel_size+=1;\n    }\n    cv::namedWindow("Process window", 1);\n    cv::createTrackbar("Sigma", "Process window", &pos_sigma, kernel_size, Process);\n    cv::createTrackbar("Lambda", "Process window", &pos_lm, 100, Process);\n    cv::createTrackbar("Theta", "Process window", &pos_th, 180, Process);\n    cv::createTrackbar("Psi", "Process window", &pos_psi, 360, Process);\n    Process(0,0);\n    cv::waitKey(0);\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n