Я пытался извлечь контурные линии из изображения, используя OpenCV 2.4.9.
Функция findContours
выполняет большую часть работы, но возвращает контурные линии
как тип vector < vector <Point> >
. Мне нужно их преобразовать в тип vector <Mat>
для последующего использования.
Я использовал конструктор класса Mat
, чтобы выполнить эту работу, и все работает нормально, пока я не передам результат от одной функции к другой через вызов по ссылке. Следующий код воспроизводит ошибку:OpenCV: преобразование вектора <вектор <Point>> в вектор <Mat>, проблемы с вызовом по ссылке
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
void getCont(Mat& img, vector<Mat>& cLines, int thresh)
{
//binarize the image
Mat imgBin;
threshold(img, imgBin, thresh, 255, THRESH_BINARY_INV);
//find contour lines
vector<vector<Point>> contours;
findContours(imgBin, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
//convert vector<vector<Point>> to vector<Mat>
for (int i = 0; i < contours.size(); i++)
cLines.push_back(Mat(contours[i]));
cerr << "cLines[0] in getCont:\n";
cerr << "cLines[0].rows: " << cLines[0].rows << "\n";
cerr << "cLines[0].cols: " << cLines[0].cols << "\n";
cerr << "cLines[0].channels(): " << cLines[0].channels() << "\n";
cerr << "cLines[0].type(): " << cLines[0].type() << "\n";
cerr << "cLines[0].row(0): " << cLines[0].row(0) << "\n";
cerr << endl << endl;
}
int main()
{
Mat img = imread("leaf.jpg", 0);
int thresh = 124;
vector<Mat> cLines;
getCont(img, cLines, thresh);
cerr << "cLines[0] in main:\n";
cerr << "cLines[0].rows: " << cLines[0].rows << "\n";
cerr << "cLines[0].cols: " << cLines[0].cols << "\n";
cerr << "cLines[0].channels(): " << cLines[0].channels() << "\n";
cerr << "cLines[0].type(): " << cLines[0].type() << "\n";
cerr << "cLines[0].row(0): " << cLines[0].row(0) << "\n";
return 0;
}
Ошибка возникает в основном в линии, предшествующий оператор возврата, когда я пытаюсь напечатать первую строку первого элемента cLines
. Для разных входных изображений я либо получаю сообщение, которое говорит мне, что .exe работает некорректно и должен выйти, либо значения действительно распечатываются, но они отличаются от вывода функции getCont
(в основном, I получить отрицательные значения, так что похоже, что есть переполнение). Я использую Visual Studio 2013 Express для Windows 8, 64-битной машины (но я использую библиотеки DLL x86 для OpenCV). Может ли кто-нибудь воспроизвести ошибку в другой системе?
Я думал, что был какой-то неявный тип, поэтому я распечатал размер и тип cLines
в getCont
и main
, но результаты одинаковые. Ошибка не возникает, когда я помещаю код функции getCont
в main
, чтобы избежать дополнительного вызова функции. Кроме того, все отлично работает, когда я заменить петлю
for (int i = 0; i < contours.size(); i++)
cLines.push_back(Mat(contours[i]));
следующим:
for (int i = 0; i < contours.size(); i++)
{
vector<Point> currPts = contours.at(i);
Mat currLine(currPts.size(), 1, CV_32SC2);
for (int j = 0; j < currPts.size(); j++)
{
currLine.at<Vec2i>(j, 0).val[0] = currPts.at(j).x;
currLine.at<Vec2i>(j, 0).val[1] = currPts.at(j).y;
}
cLines.push_back(currLine);
}
Кто-нибудь знает, что происходит?
Не должно ли объявление 'cLines' быть похоже на' Mat currLine (currPts.size(), 1, CV_32SC2); '? В основном, нигде он не говорит 'CV_32SC2'. –
@ a-Jays: Спасибо за ваш ответ. Я не устанавливаю явно тип, когда объявляю cLines, но вывод cLines [0] .type() равен 12 (это CV_32SC2 в перечислении), как в main, так и в getCont. – Kuchenschaf
Хорошо работает для меня. Вы загрузили изображение успешно? Вы можете попробовать «imshow» его проверить. – herohuyongtao