2012-06-17 35 views
14

Bất cứ ai có thể giúp tôi chuyển đổi loại vô hướng của openCV thành các kiểu cơ bản như float hay double?opencv: convert Scalar thành float hoặc double type

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

tôi phải tổng hợp tất cả các yếu tố của Mat đối tượng arg1arg2 (tổng phụ cận), sau đó tôi phải thực hiện phân chia của họ để tìm lĩnh vực định hướng tại mỗi pixel. Tôi đã thực hiện tổng hợp, nhưng vì tôi phải áp dụng hàm arctan, loại vô hướng không phù hợp. Bất cứ ai có thể giúp tôi trong việc chuyển đổi loại vô hướng thành các loại cơ bản?

thực sự tôi đang cố gắng để áp dụng log-Gabor lọc và mã tôi đã thực hiện cho đến nay là:

//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); 
    } 
} 
+0

tôi đang cố gắng áp dụng log-Gabor lọc cho tăng cường vân tay ..... tôi đã chỉnh sửa bài viết của tôi và bổ sung mã ..... – bistaumanga

Trả lời

3

EDIT

Từ các tài liệu OpenCV:

tổng số
...
Hàm func tions tổng tính toán và trả về tổng các phần tử mảng, độc lập cho mỗi kênh.

Những hình ảnh đầu ra mà Sobel tạo ra là những hình ảnh nhị phân với một kênh, như Sum1Sum2 bạn vô hướng dẫn ra khỏi bạn cần phải sử dụng atan(Sum1[0]/Sum2[0]) để tính toán giá trị chính của tangent arc.

WRONG như Log-Gabor lọc nên được áp dụng ...

Hình như bạn cố gắng làm rất nhiều thứ, có thể được xử lý bởi cv::filter2D() ... Nếu bạn muốn áp dụng một bộ lọc Gabor để hình ảnh của bạn sau đó hãy xem này, mà tôi tìm thấy 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, 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; 
} 
+0

nhờ cho câu trả lời của bạn, nhưng đây là cho gabor lọc, và i, m làm việc trên bộ lọc log-gabor ..... ít tiên tiến hơn này, nhưng nó sẽ cung cấp cho nhiều ý tưởng ...... nhưng tôi vẫn phải chuyển đổi loại vô hướng để các loại cơ bản như phao. .... bạn có thể gợi ý cho tôi phương pháp đó không ??? – bistaumanga

+0

Hãy xem bản chỉnh sửa của tôi. Hy vọng nó là chính xác – dom

23

tôi sử dụng

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

cảm ơn. câu trả lời của bạn đã giúp rất nhiều –

1

Vô hướng là một vectơ 4 phần tử của các cặp đôi có nguồn gốc từ Vec, như thể hiện trong tài liệu opencv (http://docs.opencv.org/2.4.9/modules/core/doc/basic_structures.html#scalar)

Hàm cv :: tổng các phần tử từ mỗi kênh riêng biệt, nếu ma trận có nhiều hơn một kênh, và lưu trữ chúng trên Scalar Vec. Vì vậy, để truy cập vào tăng gấp đôi cho mỗi kênh, bạn phải truy cập vào các vị trí trên vectơ. (Tài liệu: 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 vấn đề liên quan