Я обрабатываю UHD (2160 x 3840) изображения. Одна из обработок, которую я выполняю, состоит в обработке фильтрации Собеля по оси X и Y, тогда мне нужно умножить каждую выходную матрицу на ее транспонирование, а затем обработать градиентное изображение как квадратный корень из суммы градиента.интерфейс Контейнеры для контейнеров OpenCV с blas для умножения матрицы
So: S = sqrt (S_x * S_x^t + S_y * S_y^t).
Из-за размера изображения OpenCV занимает до двадцати секунд для обработки без многопоточности и десяти с многопоточным.
Я знаю, что OpenCV вызывает OpenCL, чтобы ускорить операции фильтрации, поэтому я думаю, что это может занять много времени, чтобы попытаться получить производительность с этапа фильтрации.
Для матричного умножения я испытываю нестабильность от реализации ядра OpenCV с открытым ядром.
Так что я хотел бы попробовать использовать OpenBLAS insted.
Мои вопросы:
1.)
Я написал следующий код, но я сталкиваюсь некоторые проблемы для объектов, Матем интерфейсного OpenCV в:
template<class _Ty>
void mm(cv::Mat& A,cv::Mat& B,cv::Mat& C)
{
static_assert(true,"support matrix_multiply is only defined for floating precision numbers.");
}
template<>
inline void mm<float>(cv::Mat& A,cv::Mat& B,cv::Mat& C)
{
const int M = A.rows;
const int N = B.cols;
const int K = A.cols;
cblas_sgemm(CblasRowMajor ,// 1
CblasNoTrans, // 2 TRANSA
CblasNoTrans, // 3 TRANSB
M, // 4 M
N, // 5 N
K, // 6 K
1., // 7 ALPHA
A.ptr<float>(),//8 A
A.rows, //9 LDA
B.ptr<float>(),//10 B
B.rows, //11 LDB
0., //12 BETA
C.ptr<float>(),//13 C
C.rows); //14 LDC
}
template<>
inline void mm<double>(cv::Mat& A,cv::Mat& B,cv::Mat& C)
{
cblas_dgemm(CblasRowMajor,CblasNoTrans,CblasNoTrans,A.rows,B.cols,A.cols,1.,A.ptr<double>(),A.rows,B.ptr<double>(),B.cols,0.,C.ptr<double>(),C.rows);
}
void matrix_multiply(cv::InputArray _src1, cv::InputArray _src2, cv::OutputArray _dst)
{
CV_DbgAssert( (_src1.isMat() || _src1.isUMat()) && (_src1.kind() == _src2.kind()) &&
(_src1.depth() == _src2.depth()) && (_src1.depth() == CV_32F) && (_src1.depth() == _src1.type()) &&
(_src1.rows() == _src2.cols())
);
cv::Mat src1 = _src1.getMat();
cv::Mat src2 = _src2.getMat();
cv::Mat dst;
bool cpy(false);
if(_dst.rows() == _src1.rows() && _dst.cols() == _src2.cols() && _dst.type() == _src1.type())
dst = _dst.getMat();
else
{
dst = cv::Mat::zeros(src1.rows,src2.cols,src1.type());
cpy = true;
}
if(cpy)
dst.copyTo(_dst);
}
Я пытался организовать ДАННЫЕ, как указано здесь: http://www.netlib.org/lapack/explore-html/db/dc9/group__single__blas__level3.html#gafe51bacb54592ff5de056acabd83c260
без успешных действий. Это мой главный вопрос
2.) Я думал, чтобы попытаться ускорить немного моей реализации, чтобы применить разделяй и властвуй подход иллюстрируется здесь:
https://en.wikipedia.org/wiki/Matrix_multiplication_algorithm
Но только четыре подматрицы. Пробовал ли какой-либо подобный подход или получил лучший способ повысить производительность при умножении матрицы (без использования GPU)?
Заранее благодарю за любую помощь.