最近,我从opencv-python切换到了opencv的c ++版本,因为我想使用CUDA加快我的实时视频处理应用程序。我是C ++的新手,因此在优化代码时发现了一些不清楚的内存管理时刻。
例如,我有一些这样的过滤器链:
void apply_blue_edgess(cv::Mat& matrix, cv::Mat& mask, cv::Mat& inverted_mask) {
cv::Mat gray_image, blured, canny, canny_3d, in_range_mask;
cv::cvtColor( matrix, gray_image, CV_BGR2GRAY );
cv::GaussianBlur( gray_image, blured, cv::Size( 5, 5 ), 0, 0 );
cv::Canny(blured, canny, 0, 100);
cv::cvtColor( canny, canny_3d, CV_GRAY2BGR );
cv::inRange(canny_3d, cv::Scalar(255,255,255), cv::Scalar(255,255,255), in_range_mask);
canny_3d.setTo(cv::Scalar(0, 171, 255), in_range_mask);
cv::GaussianBlur( canny_3d, matrix, cv::Size( 5, 5 ), 0, 0 );
cv::bitwise_and(matrix, mask, matrix);
}
可以在过滤器链的每一步使用新的Mat对象(gray_image, blured, canny, canny_3d, in_range_mask
)吗?这样的连续内存分配对性能不利吗?如果是这样,我应该如何编写类似的函数?
正如评论部分所建议的,我最终进行了函子包装:
struct blue_edges_filter {
blue_edges_filter(int width, int height)
: gray_image(width, height, CV_8UC1),
blured(width, height, CV_8UC1),
canny(width, height, CV_8UC1),
canny_3d(width, height, CV_8UC3),
in_range_mask(width, height, CV_8UC3)
{ }
int operator()(cv::Mat& matrix, cv::Mat& mask, cv::Mat& inverted_mask) {
cv::bitwise_and(matrix, mask, internal_mask_matrix);
cv::bitwise_and(matrix, inverted_mask, external_mask_matrix);
cv::cvtColor( matrix, gray_image, CV_BGR2GRAY );
cv::GaussianBlur( gray_image, blured, cv::Size( 5, 5 ), 0, 0 );
cv::Canny(blured, canny, 0, 100);
cv::cvtColor( canny, canny_3d, CV_GRAY2BGR );
cv::inRange(canny_3d, cv::Scalar(255,255,255), cv::Scalar(255,255,255), in_range_mask);
canny_3d.setTo(cv::Scalar(0, 171, 255), in_range_mask);
cv::GaussianBlur( canny_3d, matrix, cv::Size( 5, 5 ), 0, 0 );
cv::bitwise_and(matrix, mask, matrix);
}
private:
cv::Mat gray_image, blured, canny, canny_3d, in_range_mask;
};
//Usage
blue_edges_filter apply_blue_edgess(1024, 576);
apply_blue_edgess(matrix, mask, inverted_mask);
答案 0 :(得分:-3)
您可以重新使用内存而无需分配。创建临时图像:
void apply_blue_edgess(cv::Mat& matrix, cv::Mat& mask, cv::Mat& inverted_mask)
{
cv::Mat tmp[2];
int srcInd = 1;
auto InvInd = [&]() -> int { return srcInd ? 0 : 1; };
cv::cvtColor( matrix, tmp[InvInd()], CV_BGR2GRAY );
srcInd = InvInd();
cv::GaussianBlur( tmp[srcInd], tmp[InvInd()], cv::Size( 5, 5 ), 0, 0 );
srcInd = InvInd();
cv::Canny(tmp[srcInd], tmp[InvInd()], 0, 100);
srcInd = InvInd();
cv::cvtColor( tmp[srcInd], tmp[InvInd()], CV_GRAY2BGR );
srcInd = InvInd();
cv::inRange(tmp[srcInd], cv::Scalar(255,255,255), cv::Scalar(255,255,255), tmp[InvInd()]);
tmp[srcInd].setTo(cv::Scalar(0, 171, 255), tmp[InvInd()]);
cv::GaussianBlur( tmp[srcInd], matrix, cv::Size( 5, 5 ), 0, 0 );
cv::bitwise_and(matrix, mask, matrix);
}