c/c++语言开发共享opencv:将Scalar转换为float或double类型

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

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

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

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

 //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(i,j)=0.5*atan(Sum1/Sum2); } } 

    编辑

    来自OpenCV文档:



    函数sum为每个通道独立计算并返回数组元素的总和。

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

    错误,因为Log-Gaborfilter应该应用…

    看起来你试图做很多东西,可以用cv::filter2D() …如果你想对你的图像应用Gabor滤镜,那么看看这个,我在这里找到:

     #include  #include  #include  #include  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(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, CV_32F, 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, CV_32F, 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", "Process window", &pos_lm, 100, Process); cv::createTrackbar("Theta", "Process window", &pos_th, 180, Process); cv::createTrackbar("Psi", "Process window", &pos_psi, 360, Process); Process(0,0); cv::waitKey(0); return 0; } 

    我用

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

    标量是从Vec派生的双元素的4元素向量,如opencv文档中所示( )

    如果矩阵具有多个通道,函数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]; 

      以上就是c/c++开发分享opencv:将Scalar转换为float或double类型相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/549322.html

      (0)
      上一篇 2021年1月14日
      下一篇 2021年1月14日

      精彩推荐