I am trying to reimplement an algorithm from matlab, which uses convolution, however when testing the speed of an equivalent algorithm in opencv, I noticed that opencv's filter2d is more than 3-4x slower than matlab's conv2. What is going on? I am running the C using visual studio 2022
C :
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <chrono>
#include <numeric>
using namespace cv;
int main()
{
std::string image_path = samples::findFile("Starry_Night.jpg");
Mat img = imread(image_path, IMREAD_GRAYSCALE);
if (img.empty())
{
std::cout << "Could not read the image: " << image_path << std::endl;
return 1;
}
Mat kernelH(1, 3, CV_32F);
kernelH.at<float>(0, 0) = 1.0f;
kernelH.at<float>(0, 1) = 0.0f;
kernelH.at<float>(0, 2) = -1.0f;
Mat x_derivative;
std::array<float,1000> times = { 0 };
for (int i = 0; i < 1000; i ) {
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
filter2D(img, x_derivative, -1, kernelH, Point(-1, -1), 0, BORDER_DEFAULT);
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
times[i] = std::chrono::duration_cast<std::chrono::milliseconds> (end - begin).count();
}
double average = std::accumulate(times.begin(), times.end(), 0.0) / times.size();
std::cout << average;
imshow("Display window", x_derivative);
int k = waitKey(0); // Wait for a keystroke in the window
if (k == 's')
{
imwrite("starry_night.png", img);
}
return 0;
}
MATLAB:
img = rgb2gray(imread("Starry_Night.jpg"));
kernel = [-1 0 1];
times = zeros(1000,1);
for i = 1:1000
tic
der = conv2(img, kernel);
times(i) = toc;
end
mean(times)*1000
CodePudding user response:
Thank you everyone for the advice, what I took from this is that matlab genuinely is this optimized, and nothing is going wrong. I ended up using matlab coder to create a C library from the native matlab implementation, which ended up being faster in C than the matlab code. Realistically, unless I want to write a bespoke CUDA accelerated algorithm, MATLAB is hard to beat.