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文档:
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; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |