Sie scheinen ein paar falsche Annahmen gemacht haben.
std::vector
hat seine Elemente speichern aneinander angrenzend in einem Speicher, aber cv::Mat
ist ein Header einen Zeiger auf seinen internen Puffer enthält, so nur Zeiger in vector<Mat>
gespeichert sind aneinander angrenzend, nicht die Daten selbst, Mat. Aus diesem Grund ist der Speicher, der zwischen (float*)regionFeaMat[0].dataend
und (float*)regionFeaMat[80].datastart
liegt, ein zufälliger Müll - wenn er andere Mat-Daten teilweise enthält, ist es pures Glück.
Aufgrund der obigen Angaben können Sie keinen Vektor mit einem Liner zuordnen und müssen stattdessen jede Matte separat einfügen. Probieren Sie etwas wie folgt aus:
// prevent vector reallocation after each Mat insertion:
regionFeaVec.reserve(regionFeaMat.size()*regionFeaMat[0].cols*regionFeaMat[0].rows);
for (int i = 0; i < regionFeaMat.size(); ++i)
{
if (regionFeaMat[i].isContinuous())
regionFeaVec.insert(
regionFeaVec.end(),
(float*)regionFeaMat[i].datastart,
(float*)regionFeaMat[i].dataend
);
else
{
for (int j = 0; j < regionFeaMat[i].rows; ++j)
{
const float* row = regionFeaMat[i].ptr<float>(j);
regionFeaVec.insert(regionFeaVec.end(), row, row + regionFeaMat[i].cols);
}
}
}
Bitte beachte, dass ich überprüft habe, ob ein bestimmtes Objekt Mat kontinuierlich ist, weil nach OpenCV docs, jede Zeile Lücken am Ende in einigen Fällen enthalten kann, und in diesem Fall müssen wir Lesen Sie die Matrix Zeile für Zeile.
Dieser Code kann vereinfacht werden, denn wenn Matrix kontinuierlich ist, können wir es als 1D-Vektor gemäß den oben genannten Dokumente behandeln kann:
// prevent vector reallocation after each Mat insertion:
regionFeaVec.reserve(regionFeaMat.size()*regionFeaMat[0].cols*regionFeaMat[0].rows);
for (int i = 0; i < regionFeaMat.size(); ++i)
{
cv::Size size = regionFeaMat[i].size();
if (regionFeaMat[i].isContinuous())
{
size.width *= size.height;
size.height = 1;
}
for (int j = 0; j < size.height; ++j)
{
const float* row = regionFeaMat[i].ptr<float>(j);
regionFeaVec.insert(regionFeaVec.end(), row, row + size.width);
}
}
Wenn Sie Vektor Umschichtung in allgemeineren Fällen verhindern wollen, Sie müssen auch die Berechnungsmethode für die Anzahl der Elemente ändern, die an reserve()
übergeben werden. Die von mir verwendete Methode geht davon aus, dass alle Mat-Objekte nur zwei Dimensionen haben, die für alle Objekte gleich sind, da Sie so Ihr Problem beschrieben haben.
Auch wenn Sie es vector<float>
zuweisen möchten, stellen Sie sicher, dass der Elementtyp regionFeaMat
CV_32F
ist.
thanx Mann, aber ich habe diesen Fehler in 'regionFeaVec.insert (...)' line: 'Severity \t-Code \t Beschreibung Projekt \t Datei \t Linie \t Unterdrückungszustand Fehler (aktiv) \t keine Instanz von überladener Funktion„std: : vector <_Ty, _Alloc> :: einfügen [mit _Ty = float, _Alloc = std :: allocator ] "entspricht der Liste der Argumente" –
Oh, ich sehe, ich habe einen Fehler gemacht. Einfügen nimmt Iterator als erstes Argument, also sollte end(), nicht size() sein. Siehe meine korrigierte Antwort :) – KjMag
cv :: Mat puffs Zeilen zu einer 32-Bit-Grenze, so ist es unwahrscheinlich, dass ein Float-Typ nicht zusammenhängend wäre –