свертка: conv2 matlab в opencv

Если я установлю входное изображение и ядро ​​​​в:

cv::Mat conv2D(cv::Mat input,cv::Mat kernel){
    printf("\nINPUT [ %d x %d ]\n",input.rows,input.cols);
    cout << input <<endl;
    printf("\nKERNEL [ %d x %d ]\n",kernel.rows,kernel.cols);
    cout << kernel <<endl;

    cv::Mat flipped_kernel;
    cv::Point2i pad;
    cv::Mat result;
    cv::Mat padded;
    cv::Point anchor(kernel.cols -kernel.cols/2 -1,kernel.rows -kernel.rows/2 -1 );
    cv::flip( kernel, flipped_kernel, -1 );
    printf("\nFLIPPED KERNEL [ %d x %d ]\n",flipped_kernel.rows,flipped_kernel.cols);
    cout << flipped_kernel <<endl;
    pad = cv::Point2i( kernel.cols - 1, kernel.rows - 1);
    cv::copyMakeBorder( input, padded, pad.y, pad.y, pad.x, pad.x, cv::BORDER_CONSTANT,cv::Scalar(0) );
    cv::Rect region = cv::Rect( pad.x / 2, pad.y / 2, padded.cols - pad.x, padded.rows - pad.y);

    cv::filter2D( padded, result , padded.depth(), flipped_kernel, anchor, 0, cv::BORDER_CONSTANT );
    cv::Mat out = result( region );

    printf("\nOUT [ %d x %d ]\n",out.rows,out.cols);
    cout << out <<endl;
    return out;
}

Выход отличается от:

conv2(input,kernel)

Читая в Интернете, кто-то говорит, что флип - это ошибка, а другие говорят, что это не так. Поэтому я использовал матрицу, симметричную вращению, в качестве ядра, но результат все равно был неправильным. Как я могу выполнить 2D-свертку и 2D-взаимную корреляцию в С++?


person Michele    schedule 23.11.2018    source источник
comment
Этот conv2(input,kernel) находится в Matlab? так что вы, видимо, хотите сделать на C ++ с помощью OpenCV, что этот conv2 делает в Matlab?   -  person Duck Dodgers    schedule 24.11.2018
comment
да, это функция Matlab, которая выполняет свертку между двумя матрицами   -  person Michele    schedule 24.11.2018
comment
вы знаете, что функции conv2() передается больше параметров. В зависимости от того, что вы укажете в качестве третьего параметра, результат будет немного отличаться, несмотря на одинаковые входные матрицы. Вы можете выбрать "такой же", "полный" или "действительный" в качестве третьего параметра. Итак, попробуйте conv2 (вход, ядро, «то же самое»). Ваш результат совпадает с этим?   -  person Duck Dodgers    schedule 24.11.2018
comment
Нет, результат все еще другой, с тем же размером возвращаемой матрицы, но проблема заключается в возвращаемых значениях матрицы. В opencv вернуть некоторое отрицательное значение. Я пытаюсь преобразовать функцию Matlab в С++.   -  person Michele    schedule 24.11.2018
comment
Можете ли вы дать нам небольшой образец матриц input и kernel, которые дают вам неправильные значения в OpenCV? Вам не нужно указывать привязку (просто используйте Point(-1,-1)). Вам также не нужно использовать copyMakeBorder (просто укажите BORDER_CONSTANT в filter2D).   -  person beaker    schedule 25.11.2018
comment
Я использовал матрицу 10x10 со всеми нулями, кроме границы с 1 и угла с 2. Эта матрица используется для ядра и для ввода   -  person Michele    schedule 25.11.2018


Ответы (1)


Проблема заключалась в том, что я передал маты opencv типа CV_32F, и это дало мне неправильный результат, я преобразовал изображения в CV_8UC1 с помощью метода:

input.convertTo (вход, CV_8UC1); flipped_kernel.convertTo (вход, CV_8UC1);

И изменить после операции тип вывода:

out.convertTo (вход, CV_32F);

Так что метод работает!

person Michele    schedule 26.11.2018