2012-07-31 39 views
10

Làm thế nào để xác định mảng trong C++/Open CV như tôi làm trong MATLAB?Mảng kiểu Matlab trong C++

ví dụ:

x=a:b:c; 

hoặc

y=linspace(a,b,n); 
+0

Câu trả lời hay cho câu hỏi tương tự [tại đây] (https://stackoverflow.com/a/27030598/3079302). – iled

Trả lời

9

Tham khảo câu trả lời trước cho câu trả lời chung cho câu hỏi của bạn.

Cụ thể, để giải quyết hai ví dụ mà bạn đề cập, đây là một số tương đương với C++ mã sử dụng vectơ để tự động tạo ra các mảng mà bạn đề cập (chưa được kiểm tra):

#include <vector> 
using std::vector; 

vector<double> generateRange(double a, double b, double c) { 
    vector<double> array; 
    while(a <= c) { 
     array.push_back(a); 
     a += b;   // could recode to better handle rounding errors 
    } 
    return array; 
} 

vector<double> linspace(double a, double b, int n) { 
    vector<double> array; 
    double step = (b-a)/(n-1); 

    while(a <= b) { 
     array.push_back(a); 
     a += step;   // could recode to better handle rounding errors 
    } 
    return array; 
} 
+1

preallocation điền vào 'mảng' với giá trị' n', sau đó 'push_back' nối thêm các giá trị' n' vào cuối, vì vậy bạn nên bỏ preallocation – YuppieNetworking

+0

Cảm ơn @YuppieNetworking. Tôi đã nhầm lẫn ngôn ngữ, suy nghĩ các nhà xây dựng được phân bổ mà không cần điền. Tôi đã loại bỏ preallocation, vì sử dụng 'push_back'. – mattgately

+0

@mattgately, bạn có thể sử dụng chức năng 'dự trữ 'để có hiệu quả hơn. –

3

OpenCV cung cấp một số chức năng tương tự như Matlab, nhưng con số của họ là rất hạn chế.

Bạn có thể

cv::Mat a = cv::Mat::eye(5); 
cv::Mat b = cv::Mat::zeros(5); 
cv::Mat img = cv::imread("myGorgeousPic.jpg"); 
cv::imwrite(img, "aCopyOfMyGorgeousPic.jpg"); 

Nó cũng hỗ trợ diag()

Nhưng đối với hầu hết rằng chức năng phức tạp Matlab như linspace hoặc magic hoặc bất cứ điều gì, không có phóng viên trong OpenCV, chủ yếu là vì OpenCV không phải là một toán học gói, nhưng một tầm nhìn máy tính một. Nếu bạn cần một số chức năng cụ thể, bạn có thể sao chép nó trong dự án của bạn (hay tự viết nó)

3

Thật không may là C++ không có sẵn để cho phép kiểu khởi tạo ma trận này. Nó hỗ trợ mảng đa chiều nhưng bạn sẽ cần tự khởi tạo mọi phần tử. C++ là một ngôn ngữ cấp thấp hơn so với Matlab và nó liên quan đến nhiều công việc hơn để viết các chức năng để tạo và khởi tạo một biến kiểu ma trận.

Có nói rằng có một số thư viện có sẵn để sử dụng với C++ giúp tính toán số dễ dàng hơn nếu bạn cố tự mình viết. Nếu bạn cần xem xét sử dụng thư viện, hãy xem liên kết này đề xuất một số liên kết phù hợp https://scicomp.stackexchange.com/questions/351/recommendations-for-a-usable-fast-c-matrix-library

1

Đây là một thực hiện đơn giản nếu bạn sử dụng openCV.

Mat linspace(double &startP,double &Endp,int &interval) 
{ 
    double spacing = interval-1; 
    Mat y(spacing,1,CV_64FC1); 
    for (int i = 0; i < y.rows; ++i) 
    { 
     y.at<double>(i) = startP + i*(Endp - startP)/spacing; 
    } 
    return y; 
} 
1
double* linspace(int xi, int xf, unsigned int n){ 
double *vec ; 
vec = new double[n]; 
float esp, falt=xf-xi; 
esp=falt/(n-1); 
vec[0]=xi; 
for(int i=1; i<n; i++) 
    vec[i]=vec[i-1]+esp; 
return vec; 
+1

Câu trả lời của bạn nên có giải thích về mã của bạn và mô tả cách giải quyết vấn đề. – AbcAeffchen

1

đây là linspace thử nghiệm của tôi rất giống với tất cả những người khác nhưng xử lý tất cả các trường hợp:

vector<double> Utilities::Linspace(double a, double b, int n) { 
    vector<double> array; 
    double epsilon = 0.0001; 
    double step = (b-a)/(n-1); 
    if (a==b) 
    { 
     for (int i = 0; i < n; i++) 
     { 
      array.push_back(a); 
     } 
    } 
    else if (step >= 0) 
    { 
     while(a <= b + epsilon) 
     { 
      array.push_back(a); 
      a += step;   
     }  
    } 
    else 
    { 
     while(a + epsilon >= b) 
     { 
      array.push_back(a); 
      a += step;   
     }  
    } 
    return array; 
} 
+0

Lỗi cổ điển chia cho số không khi 'n = 1' ... Tôi đã đăng một số thay đổi nhỏ (xem bên dưới) – champost

0

Gia hạn @ câu trả lời Gilad của trên đối với trường hợp khi n=0n=1 vì sau này cung cấp cho tăng lên phân chia bằng không.

vector<double> linspace(double a, double b, int n) { 
    vector<double> array; 
    if ((n == 0) || (n == 1) || (a == b)) 
     array.push_back(b); 
    else if (n > 1) { 
     double step = (b - a)/(n - 1); 
     int count = 0; 
     while(count < n) { 
      array.push_back(a + count*step); 
      ++count; 
     } 
    } 
    return array; 
} 
+0

mã của bạn không xử lý được trường hợp khi bước là -ve. (b> a hoặc b ankittie

+0

@ankittie điều gì khiến bạn nói rằng, bạn đã thử mã chưa? 'bước' là kiểu' double' và có thể là + ve hoặc -ve. – champost

1

Tôi muốn thêm sửa đổi nhỏ vào mã được đề xuất một cách mờ nhạt.Tôi sử dụng nó và có một số trường hợp khi step không tính toán một cách chính xác do xấp xỉ phân chia

double step = (b-a)/(n-1); 

Tôi chỉ cần thêm một số nhỏ đến tình trạng while:

while(a <= b+0.00001) 

Như thế này nó làm việc với tôi và số khoảng thời gian chính xác đã được tạo.