opencv Mehrkanalelementzugriffs
-
22-07-2019 - |
Frage
Ich versuche zu lernen, wie OpenCV die neue C ++ Schnittstelle zu verwenden.
Wie kann ich Zugriff auf Elemente einer Multi-Channel-Matrix. zum Beispiel:
Mat myMat(size(3, 3), CV_32FC2);
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
//myMat_at_(i,j) = (i,j);
}
}
Was ist der einfachste Weg, dies zu tun? So etwas wie cvSet2D der alten Schnittstelle
Was ist die efficiant Art und Weise? Ähnlich wie mit direkten Zeiger in der alten Schnittstelle.
Danke
Lösung
typedef struct elem_ {
float f1;
float f2;
} elem;
elem data[9] = { 0.0f };
CvMat mat = cvMat(3, 3, CV_32FC2, data );
float f1 = CV_MAT_ELEM(mat, elem, row, col).f1;
float f2 = CV_MAT_ELEM(mat, elem, row, col).f2;
CV_MAT_ELEM(mat, elem, row, col).f1 = 1212.0f;
CV_MAT_ELEM(mat, elem, row, col).f2 = 326.0f;
Update: für OpenCV2.0
1. Wählen Sie eine Art des Elements
darstellen
Mat (oder CvMat) hat 3. Abmessungen: Reihe, Spalte, Kanal
Wir können ein Element zuzugreifen (oder Pixel) in der Matrix, die durch die Reihe und Spalte angeben.
CV_32FC2
bedeutet das Element 32bit Gleitkommawert mit 2 Kanälen.
So elem in obigem Code eine akzeptable Darstellung CV_32FC2
ist.
Sie können andere Darstellungen verwenden Sie möchten. Zum Beispiel:
typedef struct elem_ { float val[2]; } elem;
typedef struct elem_ { float x;float y; } elem;
OpenCV2.0 fügt einige neue Typen das Element in der Matrix darstellen, wie:
template<typename _Tp, int cn> class CV_EXPORTS Vec // cxcore.hpp (208)
So wir Vec<float,2>
können CV_32FC2
darstellen, oder -nutzung:
typedef Vec<float, 2> Vec2f; // cxcore.hpp (254)
Sehen Sie den Quellcode, um weitere Art, die Ihr Element darstellen kann.
Hier verwenden wir Vec2f
2. Zugriff auf das Element
Die einfachste und efficiant Weise das Element in der Mat-Klasse zuzugreifen, ist Mat :: at.
Es verfügt über 4 Überlastungen:
template<typename _Tp> _Tp& at(int y, int x); // cxcore.hpp (868)
template<typename _Tp> const _Tp& at(int y, int x) const; // cxcore.hpp (870)
template<typename _Tp> _Tp& at(Point pt); // cxcore.hpp (869)
template<typename _Tp> const _Tp& at(Point pt) const; // cxcore.hpp (871)
// defineded in cxmat.hpp (454-468)
// we can access the element like this :
Mat m( Size(3,3) , CV_32FC2 );
Vec2f& elem = m.at<Vec2f>( row , col ); // or m.at<Vec2f>( Point(col,row) );
elem[0] = 1212.0f;
elem[1] = 326.0f;
float c1 = m.at<Vec2f>( row , col )[0]; // or m.at<Vec2f>( Point(col,row) );
float c2 = m.at<Vec2f>( row , col )[1];
m.at<Vec2f>( row, col )[0] = 1986.0f;
m.at<Vec2f>( row, col )[1] = 326.0f;
3. Interaktion mit alter Schnittstelle
Mat bietet 2 Konvertierungsfunktionen:
// converts header to CvMat; no data is copied // cxcore.hpp (829)
operator CvMat() const; // defined in cxmat.hpp
// converts header to IplImage; no data is copied
operator IplImage() const;
// we can interact a Mat object with old interface :
Mat new_matrix( ... );
CvMat old_matrix = new_matrix; // be careful about its lifetime
CV_MAT_ELEM(old_mat, elem, row, col).f1 = 1212.0f;
Andere Tipps
Vic Sie müssen Vec3b anstelle von Vec3i:
for (int i=0; i<image.rows; i++)
{
for (int j=0; j<image.cols; j++)
{
if (someArray[i][j] == 0)
{
image.at<Vec3b>(i,j)[0] = 0;
image.at<Vec3b>(i,j)[1] = 0;
image.at<Vec3b>(i,j)[2] = 0;
}
}
}
Sie können das zugrunde liegende Datenfeld direkt zugreifen:
Mat myMat(size(3, 3), CV_32FC2);
myMat.ptr<float>(y)[2*x]; // first channel
myMat.ptr<float>(y)[2*x+1]; // second channel
es hängt von dem Datentyp der Matte Sie verwenden, wenn es numerisch wie CV_32FC1 ist Sie können verwendet werden:
myMat.at<float>(i, j)
Wenn es ein uchar Typ, dann können Sie ein Element zugreifen mit
(symb.at<Vec3b>(i, j)).val[k]
k ist, wo der Kanal, das ist 0 für Graustufenbilder und 3 für farbige
Die beste Art Multi-Kanal-Array mit der C ++ api zuzugreifen ist durch einen Zeiger auf eine bestimmte Zeile unter Verwendung der PTR-Methode zu schaffen.
Zum Beispiel:
type elem = matrix.ptr<type>(i)[N~c~*j+c]
mit
- Typ : der Datentyp (float, int, char ect ..)
- i : Zeile, die Sie interessiert sind in
- Nc : die Anzahl der Kanäle
- j : die Spalte, die Sie interessiert sind
- c : die Spalte, die Sie interessiert sind (0-3)
Weitere Informationen zu anderen c-> c ++ Umwandlung diesen Link finden Sie unter: Quelle