Jak zdefiniować tablice w C++/Otwórz CV tak jak w Matlabie?Macierze typu Matlab w C++
na przykład:
x=a:b:c;
lub
y=linspace(a,b,n);
Jak zdefiniować tablice w C++/Otwórz CV tak jak w Matlabie?Macierze typu Matlab w C++
na przykład:
x=a:b:c;
lub
y=linspace(a,b,n);
Skorzystaj z poprzednich odpowiedzi, aby uzyskać ogólne odpowiedzi na swoje pytanie.
szczególności, aby rozwiązać te dwa przykłady, które można wymienić, jest tu jakiś równoważny kod C++ przy użyciu wektorów do dynamicznego generowania tablic pan wspomniał (nie testowane):
#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;
}
przedalokacja wypełnia 'tablicę' wartościami 'n', następnie' push_back' dołącza do wartości 'n' do końca, więc powinieneś upuścić prealokację – YuppieNetworking
dzięki @YuppieNetworking. Myliłem języki, myśląc, że konstruktor przydzielony bez wypełniania. Usunąłem wstępną alokację, ponieważ używam 'push_back'. – mattgately
@mattgately, możesz użyć funkcji 'reserve', aby była bardziej efektywna. –
OpenCV oferuje kilka funkcji, które są podobne do Matlab, ale ich liczba jest bardzo ograniczona.
Można
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");
Obsługuje również diag()
Ale dla większości z tej skomplikowanej funkcjonalności Matlab jak linspace
lub magic
czy cokolwiek innego, nie ma korespondent w OpenCV, głównie dlatego OpenCV nie jest matematyka pakiet, ale komputerowa wizja. Jeśli potrzebujesz jakiejś konkretnej funkcji, możesz sklonować ją w projekcie (pisz ją samodzielnie).
Niestety, C++ nie ma wbudowanego w nią nic, aby umożliwić tego rodzaju inicjalizację macierzy. Obsługuje tablice wielowymiarowe, ale musisz sam zainicjalizować każdy element. C++ jest językiem niższego poziomu niż Matlab i wymaga znacznie więcej pracy, aby napisać funkcjonalność do tworzenia i inicjowania zmiennej typu matrix.
Powiedziawszy, że istnieje wiele bibliotek dostępnych do użycia z C++, które ułatwiają obliczenia numeryczne, niż gdybyś sam próbował je napisać. Jeśli chcesz rozważyć korzystanie z bibliotek, zapoznaj się z tym linkiem, który sugeruje kilka odpowiednich: https://scicomp.stackexchange.com/questions/351/recommendations-for-a-usable-fast-c-matrix-library
Jest to prosta implementacja jeśli używasz 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;
}
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;
Twoja odpowiedź powinna zawierać objaśnienie kodu i opis sposobu rozwiązania problemu. – AbcAeffchen
tutaj jest mój sprawdzony linspace bardzo podobna do wszystkich innych, ale obsługuje wszystkie przypadki:
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;
}
Klasyczny błąd dzielenia przez zero, gdy 'n = 1' ... Przesłałem kilka drobnych zmian (patrz poniżej) – champost
Przedłużenie @ odpowiedź Gilada powyżej dla przypadków, kiedy n=0
i n=1
ponieważ ostatni daje wzrost do podziału przez zero.
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;
}
Chciałbym dodać niewielką modyfikację kodu zaproponowanego przez mattgately.Używałem go i istnieją pewne przypadki, gdy step
nie jest prawidłowo obliczone ze względu na podział zbliżenia
double step = (b-a)/(n-1);
Właśnie dodałem niewielką liczbę do stanu while
:
while(a <= b+0.00001)
Podobnie jak to, że pracował ze mną została utworzona prawidłowa liczba interwałów.
Dobra odpowiedź na podobne pytanie [tutaj] (https://stackoverflow.com/a/27030598/3079302). – iled