加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-16 09:12:55 所属栏目:安全 来源:网络整理
导读:任何人可以帮助我将标量类型的openCV转换为基本类型,如float或double? Scalar Sum1=sum(arg1),Sum2=sum(arg2);theta.atfloat(i,j)=0.5*atan(Sum1/Sum2); 我必须对Mat对象arg1和arg2(邻域和)的所有元素求和,然后我必须执行它们的除法以在每个像素处找到方向
任何人可以帮助我将标量类型的openCV转换为基本类型,如float或double?

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

我必须对Mat对象arg1和arg2(邻域和)的所有元素求和,然后我必须执行它们的除法以在每个像素处找到方向域.我执行了sum,但由于我必须应用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,3);
Sobel(fImage,3);    
Sobel(fImage,2,3);

//orientation estimation

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

copyMakeBorder(grad2_x,Scalar::all(0));

copyMakeBorder(grad_y,Scalar::all(0));

copyMakeBorder(grad2_y,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,j+block.width/2));

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

        Mat roi_gradY2=grad2_y(Range(i-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);
    }
}

解决方法

编辑

从OpenCV文档:

sum

The functions sum calculate and return the sum of array elements,
independently for each channel.

Sobel生成的输出图像是具有一个通道的二进制图像,由于您需要使用atan(Sum1 [0] / Sum2 [0])来计算反正切的主值,因此您的Sum1和Sum2 Scalars结果.

应用错误的Log-Gabor滤波器应用…

看起来你试图做很多的东西,这可以由cv :: filter2D()处理…如果你想应用一个Gabor过滤器到你的图像,那么看看这个,我发现here:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <math.h>

cv::Mat mkKernel(int ks,double sig,double th,double lm,double ps)
{
    int hks = (ks-1)/2;
    double theta = th*CV_PI/180;
    double psi = ps*CV_PI/180;
    double del = 2.0/(ks-1);
    double lmbd = lm;
    double sigma = sig/ks;
    double x_theta;
    double y_theta;
    cv::Mat kernel(ks,ks,CV_32F);
    for (int y=-hks; y<=hks; y++)
    {
        for (int x=-hks; x<=hks; x++)
        {
            x_theta = x*del*cos(theta)+y*del*sin(theta);
            y_theta = -x*del*sin(theta)+y*del*cos(theta);
            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);
        }
    }
    return kernel;
}

int kernel_size=21;
int pos_sigma= 5;
int pos_lm = 50;
int pos_th = 0;
int pos_psi = 90;
cv::Mat src_f;
cv::Mat dest;

void Process(int,void *)
{
    double sig = pos_sigma;
    double lm = 0.5+pos_lm/100.0;
    double th = pos_th;
    double ps = pos_psi;
    cv::Mat kernel = mkKernel(kernel_size,sig,th,lm,ps);
    cv::filter2D(src_f,dest,kernel);
    cv::imshow("Process window",dest);
    cv::Mat Lkernel(kernel_size*20,kernel_size*20,CV_32F);
    cv::resize(kernel,Lkernel,Lkernel.size());
    Lkernel /= 2.;
    Lkernel += 0.5;
    cv::imshow("Kernel",Lkernel);
    cv::Mat mag;
    cv::pow(dest,2.0,mag);
    cv::imshow("Mag",mag);
}

int main(int argc,char** argv)
{
    cv::Mat image = cv::imread("cat.jpg",1);
    cv::imshow("Src",image);
    cv::Mat src;
    cv::cvtColor(image,src,CV_BGR2GRAY);
    src.convertTo(src_f,1.0/255,0);
    if (!kernel_size%2)
    {
        kernel_size+=1;
    }
    cv::namedWindow("Process window",1);
    cv::createTrackbar("Sigma","Process window",&pos_sigma,kernel_size,Process);
    cv::createTrackbar("Lambda",&pos_lm,100,Process);
    cv::createTrackbar("Theta",&pos_th,180,Process);
    cv::createTrackbar("Psi",&pos_psi,360,Process);
    Process(0,0);
    cv::waitKey(0);
    return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读