На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
Модераторы: JoeUser, Qraizer
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Медиана, OpenCV, массивы-векторы и пр...., Споткнулся на ровном месте...
Всем доброго времени суток!

Заставили переводить код с Питона (в нем задействована OpenCV с auto_canny). Нашел на GitHub реализацию нужной функции на C++. Что-то не понимаю я почему у меня необработанное исключение выскакивает при копировании входного Mat в вектор при определении медианы. Или туплю конкретно, или подскажите где ошибся.... Очень давно на VC++ не писал... Может, поменялось что?

VS 2015 комьюнити
Измененный немного код ниже
ExpandedWrap disabled
    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;
    }

Мелочь какая-то, ведь, скорее всего... Подскажите, ребят....
Цитата =SAPSAN= @
Input.copyTo(vecFromMat); // Copy Input Mat to vector vecFromMat <-- НА ЭТОЙ СТРОКЕ ИСКЛЮЧЕНИЕ

Какое исключение? Может быть оно ожидает не пустой вектор, а размером с оригинал?
Попробуй вектору сделать resize, перед тем как передавать его в copyTo.
Плюс ко всему, параметр передается по значению, будет создана копия:
Цитата =SAPSAN= @
double medianMat(cv::Mat Input)

Ты точно так хотел сделать? Может быть лучше по ссылке передать?
ExpandedWrap disabled
    double medianMat(cv::Mat& Input)

?
Исключение возникает "Возникло необработанное исключение по адресу 0x00007FFC8D049129 в Edges.exe: исключение Microsoft C++: cv::Exception по адресу памяти 0x00000080423DE150."
Причем без разницы каким способом передача происходит - сейчас попробовал по ссылке - выскочило то,, что указал выше
Лучше наверное привести весь код, включая то, чем инициализируется "cv::Mat &image".
Мои программные ништякиhttp://majestio.info
Цитата JoeUser @


А он (код) простенький
ExpandedWrap disabled
    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;
    }

Это без всего лишнего код
Я так понимаю, что вместо всех этих захватов можно скормить просто одно изображение для теста?
И если "да", какой формат изображения должен быть?

Добавлено
И попутно вопрос: сразу же на первой итерации валится прога?
Мои программные ништякиhttp://majestio.info
Изображение - обычный битмап
валится на первой же итерации
если не вызывать auto_canny, а сделать так
ExpandedWrap disabled
    cvtColor(frame, edges, COLOR_BGR2GRAY);
    GaussianBlur(edges, edges, Size(7, 7), 1.5, 1.5);
    Canny(edges, edges, 0, 30, 3);

то все работает
Валится все только на копировании в вектор для нахождения медианы
Цитата =SAPSAN= @
Валится все только на копировании в вектор для нахождения медианы

Так а что функция принимает, куда ты свой вектор передаешь? Может она ждет массив с выделенной памятью? Ты туда передаешь по сути пустой вектор, с 0 размером.
И текст исключения хорошо бы почитать. Перехвати его с помощью catch(cv::Exception& error) что оно там пишет то хоть?
У меня что-то в голове плохо укладывается...
Смотрите, метод Mat::copyTo() ждет матрицу на вход, а автор кода ему подсовывает вектор... Это как?

Добавлено
Код не мой - это с гитхаба.... Опередили меня
Цитата =SAPSAN= @
Смотрите, метод Mat::copyTo() ждет матрицу на вход, а автор кода ему подсовывает вектор... Это как?


Там они с перегрузками, а так если валится - копирует в невалидную память, она может быть не выделена скорее всего или недостаточно ее. Там же исходники библиотеки есть, попробуй по ним пройтись.
Цитата 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.
Мои программные ништякиhttp://majestio.info
Пишет 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"
Как-будто все как я и говорил... Или не?
Цитата Wound @
Перехвати его с помощью catch(cv::Exception& error) что оно там пишет то хоть?

Во-во ... из доки как раз:
ExpandedWrap disabled
    try
    {
        ... // call OpenCV
    }
    catch (const cv::Exception& e)
    {
        const char* err_msg = e.what();
        std::cout << "exception caught: " << err_msg << std::endl;
    }
Мои программные ништякиhttp://majestio.info
Цитата JoeUser @
Цитата Wound @
Перехвати его с помощью catch(cv::Exception& error) что оно там пишет то хоть?

Во-во ... из доки как раз:
ExpandedWrap disabled
    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'
=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.


Добавлено
Я бы посоветовал сперва добиться результата без ошибки на каком-то простом изображении.
Ну а потом бы исследовал что там камера захвата выдает. Ну и корректировал бы по ходу.
Мои программные ништякиhttp://majestio.info
1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
0 пользователей:


Рейтинг@Mail.ru
[ Script Execution time: 0,1434 ]   [ 20 queries used ]   [ Generated: 20.09.19, 20:46 GMT ]