Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.119.109.119] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Всем доброго времени суток!
Заставили переводить код с Питона (в нем задействована OpenCV с auto_canny). Нашел на GitHub реализацию нужной функции на C++. Что-то не понимаю я почему у меня необработанное исключение выскакивает при копировании входного Mat в вектор при определении медианы. Или туплю конкретно, или подскажите где ошибся.... Очень давно на VC++ не писал... Может, поменялось что? VS 2015 комьюнити Измененный немного код ниже double medianMat(cv::Mat Input) { Input = Input.reshape(0, 1);// spread Input Mat to single row std::vector<double> vecFromMat; Input.copyTo(vecFromMat); // Copy Input Mat to vector vecFromMat <-- НА ЭТОЙ СТРОКЕ ИСКЛЮЧЕНИЕ std::nth_element(vecFromMat.begin(), vecFromMat.begin() + vecFromMat.size() / 2, vecFromMat.end()); return vecFromMat[vecFromMat.size() / 2]; } cv::Mat auto_canny(cv::Mat &image, cv::Mat &output, float sigma = 0.33) { int low_H = 30, low_S = 150, low_V = 50; int high_H = 255, high_S = 255, high_V = 180; //convert to grey colour space cv::cvtColor(image, output, cv::COLOR_BGR2HSV); cv::Mat msk, res; // cv::Mat l = inRange(output, cv::Scalar(low_H, low_S, low_V), cv::Scalar(high_H, high_S, high_V), msk); bitwise_and(output, output, output, msk); //apply small amount of Gaussian blurring //cv::GaussianBlur(output, output, cv::Size(3, 3), 0, 0); //get the median value of the matrix double v = medianMat(output); //generate the thresholds //int lower = (int)std::max(0.0, (1, 0 - sigma)*v); // было так //int upper = (int)std::min(255.0, (1, 0 + sigma)*v); // было так int lower = (int)std::max(0.0, 4.0*(1, 0 - sigma)*v); // определение нижней границы фильтра; коэффициент 4 подобран вручную после сравнения ярких и тёмных полос int upper = (int)std::min(255.0, 3.5*(1, 0 + sigma)*v); // определение верхней границы фильтра; коэффициент 3.5 подобран вручную после сравнения ярких и тёмных полос //apply canny operator cv::Canny(output, output, lower, upper, 3); return output; } Мелочь какая-то, ведь, скорее всего... Подскажите, ребят.... |
Сообщ.
#2
,
|
|
|
Цитата =SAPSAN= @ Input.copyTo(vecFromMat); // Copy Input Mat to vector vecFromMat <-- НА ЭТОЙ СТРОКЕ ИСКЛЮЧЕНИЕ Какое исключение? Может быть оно ожидает не пустой вектор, а размером с оригинал? Попробуй вектору сделать resize, перед тем как передавать его в copyTo. Плюс ко всему, параметр передается по значению, будет создана копия: Цитата =SAPSAN= @ double medianMat(cv::Mat Input) Ты точно так хотел сделать? Может быть лучше по ссылке передать? double medianMat(cv::Mat& Input) ? |
Сообщ.
#3
,
|
|
|
Исключение возникает "Возникло необработанное исключение по адресу 0x00007FFC8D049129 в Edges.exe: исключение Microsoft C++: cv::Exception по адресу памяти 0x00000080423DE150."
Причем без разницы каким способом передача происходит - сейчас попробовал по ссылке - выскочило то,, что указал выше |
Сообщ.
#4
,
|
|
|
Лучше наверное привести весь код, включая то, чем инициализируется "cv::Mat &image".
|
Сообщ.
#5
,
|
|
|
Цитата JoeUser @ А он (код) простенький int main(int, char **) { VideoCapture cap(filevideo); if (!cap.isOpened()) // check if we succeeded { cout << "Cannot open the video file" << endl; cin.get(); //wait for any key press return -1; } Mat edges; namedWindow("edges", WINDOW_AUTOSIZE); for (;;) { Mat frame; cap >> frame; // get a new frame from camera double timestamp = cap.get(CAP_PROP_POS_MSEC); auto_canny(frame, edges, 0.5); imshow("edges", edges); if (waitKey(33) == 27) break; // выходим по ESC вне зависимости от раскладки } return 0; } Это без всего лишнего код |
Сообщ.
#6
,
|
|
|
Я так понимаю, что вместо всех этих захватов можно скормить просто одно изображение для теста?
И если "да", какой формат изображения должен быть? Добавлено И попутно вопрос: сразу же на первой итерации валится прога? |
Сообщ.
#7
,
|
|
|
Изображение - обычный битмап
валится на первой же итерации если не вызывать auto_canny, а сделать так cvtColor(frame, edges, COLOR_BGR2GRAY); GaussianBlur(edges, edges, Size(7, 7), 1.5, 1.5); Canny(edges, edges, 0, 30, 3); то все работает Валится все только на копировании в вектор для нахождения медианы |
Сообщ.
#8
,
|
|
|
Цитата =SAPSAN= @ Валится все только на копировании в вектор для нахождения медианы Так а что функция принимает, куда ты свой вектор передаешь? Может она ждет массив с выделенной памятью? Ты туда передаешь по сути пустой вектор, с 0 размером. И текст исключения хорошо бы почитать. Перехвати его с помощью catch(cv::Exception& error) что оно там пишет то хоть? |
Сообщ.
#9
,
|
|
|
У меня что-то в голове плохо укладывается...
Смотрите, метод Mat::copyTo() ждет матрицу на вход, а автор кода ему подсовывает вектор... Это как? Добавлено Код не мой - это с гитхаба.... Опередили меня |
Сообщ.
#10
,
|
|
|
Цитата =SAPSAN= @ Смотрите, метод Mat::copyTo() ждет матрицу на вход, а автор кода ему подсовывает вектор... Это как? Там они с перегрузками, а так если валится - копирует в невалидную память, она может быть не выделена скорее всего или недостаточно ее. Там же исходники библиотеки есть, попробуй по ним пройтись. |
Сообщ.
#11
,
|
|
|
Цитата Wound @ Так а что функция принимает, куда ты свой вектор передаешь? Может она ждет массив с выделенной памятью? Ты туда передаешь по сути пустой вектор, с 0 размером. Цитата void cv::Mat::copyTo(OutputArray m) const Copies the matrix to another one. The method copies the matrix data to another matrix. Before copying the data, the method invokes : m.create(this->size(), this->type()); so that the destination matrix is reallocated if needed. While m.copyTo(m); works flawlessly, the function does not handle the case of a partial overlap between the source and the destination matrices. When the operation mask is specified, if the Mat::create call shown above reallocates the matrix, the newly allocated matrix is initialized with all zeros before copying the data. Parameters m Destination matrix. If it does not have a proper size or type before the operation, it is reallocated. |
Сообщ.
#12
,
|
|
|
Пишет msg = "OpenCV(4.1.1) C:\\build\\master_winpack-build-win64-vc14\\opencv\\modules\\core\\src\\copy.cpp:254: error: (-215:Assertion failed) channels() == CV_MAT_CN(dtype) in function 'cv::Mat::copyTo'\n"
Как-будто все как я и говорил... Или не? |
Сообщ.
#13
,
|
|
|
Цитата Wound @ Перехвати его с помощью catch(cv::Exception& error) что оно там пишет то хоть? Во-во ... из доки как раз: try { ... // call OpenCV } catch (const cv::Exception& e) { const char* err_msg = e.what(); std::cout << "exception caught: " << err_msg << std::endl; } |
Сообщ.
#14
,
|
|
|
Цитата JoeUser @ Цитата Wound @ Перехвати его с помощью catch(cv::Exception& error) что оно там пишет то хоть? Во-во ... из доки как раз: try { ... // call OpenCV } catch (const cv::Exception& e) { const char* err_msg = e.what(); std::cout << "exception caught: " << err_msg << std::endl; } еще раз - 0x000001bae45fa070 "OpenCV(4.1.1) C:\\build\\master_winpack-build-win64-vc14\\opencv\\modules\\core\\src\\copy.cpp:254: error: (-215:Assertion failed) channels() == CV_MAT_CN(dtype) in function 'cv::Mat::copyTo' |
Сообщ.
#15
,
|
|
|
=SAPSAN=, ну не зря я про формат изображения вроде спрашивал. Похоже на то.
Вот что народ про твою ошибку пишет: Цитата The channels of your two images do not match. So you are trying to copy a bgr image to a grayscale image or something like that. Check the types of your images. Добавлено Я бы посоветовал сперва добиться результата без ошибки на каком-то простом изображении. Ну а потом бы исследовал что там камера захвата выдает. Ну и корректировал бы по ходу. |