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

War es hilfreich?

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top