OpenCV中的网络摄像头图像处理C++速度很慢
Webcam Image Processing in C++ OpenCV is Slow
我想用C++ OpenCV使用网络摄像头来模拟原生视视图(部分色盲之一)。这里的代码:
#include "opencv2/opencv.hpp"
using namespace cv;
int main(int, char**)
{
int i = 0;
Mat im, im2, kernel3;
Mat rgb2lms = (Mat_<double>(3, 3) << 17.8824, 43.5161, 4.11935, 3.45565, 27.1554, 3.86714, 0.0299566, 0.184309, 1.46709); //filter1
Mat lms2lmsp = (Mat_<double>(3, 3) << 0, 2.02344, -2.52581, 0, 1, 0, 0, 0, 1); //filter2
Mat Result, Result2, op1, op2, op3, op4, op5, op6;
Vec3b zay, zay2;
kernel3 = rgb2lms.inv(DECOMP_LU); //filter 3
cv::Mat mat(3, 1, CV_64FC1); //create MAT for matrices multiplication
Mat frame;
VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
namedWindow("edges", 1);
for (;;)
{
cap.read(frame); // get a new frame from camera
if (frame.empty()) continue;
const int nChannels = frame.channels();
if (i == 0){
Result.create(frame.size(), frame.type());
}
//Result2.create(frame.size(), frame.type());
cvtColor(frame, im2, CV_BGR2RGB); //convert to RGB
for (int i = 0; i < im2.rows; i++)
{
for (int j = 0; j < im2.cols; j++)
{
for (int k = 0; k < nChannels; k++)
{
zay(k) = im2.at<Vec3b>(i, j)[k]; //acces pixel value and put into 3x1 vector zay
//put the value in to mat so i can multiplied with easy
mat.at <double>(0, 0) = zay[0];
mat.at <double>(1, 0) = zay[1];
mat.at <double>(2, 0) = zay[2];
op1 = rgb2lms*mat; //apply filter1
op2 = lms2lmsp*op1; //apply filter2
op3 = kernel3*op2; //apply filter3
for (int k = 0; k < nChannels; k++)
{
Result.at<Vec3b>(i, j)[k] = op3.at<double>(k, 0); //put the result from vector to mat
}
}
}
cvtColor(Result, Result2, CV_RGB2BGR); //convert back to BGR
imshow("hasil", Result2);
if (waitKey(30) >= 0) break;
i++;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
此代码已运行,但图像视频输出非常慢(滞后)。 我对C++很陌生。我的问题:
- 输出很慢,因为我使用了很多迭代?
- 我已经使用filter2D(卷积)尝试了此过程,结果是不同的。卷积与矩阵乘法滤波器不同吗?
- 如何使输出流畅?我应该在该代码中使用指针吗?
谢谢
Filter2D 不是适合您的任务的函数。它在图像的每个通道上应用卷积滤波器,而您想要的是应用于每个 rgb 像素的线性变形矩阵。
您正在寻找的功能是转换。
首先,为了获得更好的性能,请将三个转换合并到单个全局转换矩阵中:
Mat global_kernel = kernel3*lms2lmsp*rgb2lms;
然后,使用
:transform(im2, Result, global_kernel);
如果您仍想节省几毫秒,您还可以通过直接从 bgr 颜色空间应用转换来删除 cvtColor 函数调用。只需切换 rgb2lms 矩阵的列:
Mat bgr2lms = (Mat_<double>(3, 3) << 4.11935, 43.5161, 17.8824, 3.86714, 27.1554, 3.45565, 1.46709, 0.184309, 0.0299566);
我认为您的问题是调用Mat::at<>()
,这很慢。为了加快速度,您可以尝试改用指针访问数据。这比较棘手,但速度要快得多。OpenCV教程展示了如何做到这一点。
相关文章:
- 为什么在读取文件大小时文件IO速度会发生变化
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- 文件系统:复制功能的速度秘诀是什么
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 在C++中使用并行化的预期速度是多少(不是 OpenMp,而是 <thread>)
- 两个连续的 OpenMP 并行区域会相互减慢速度
- 查找标准::hash_map与标准::矢量的速度
- 加快在C++中读取/处理日志文件的速度
- 为什么这些算法的运行速度比它们应该的要快?
- 如何提高文件的读取速度?
- 通过libpqxx提高PostgreSQL数据库的更新速度
- 使用 IMFSinkWriter 编码的视频的播放速度会根据宽度而变化
- 计算车辆之间的距离并设置速度,使距离保持不变,例如 5 米
- 如何加快大字符串的解析速度?
- 如何比较两个函数的速度和性能
- 线程相互减慢速度
- 多线程减慢程序速度:无错误共享,无互斥锁,无缓存未命中,无小工作量
- 使用 Unity 构建加快C++构建速度,并减少标头依赖项
- 从 OpenCV 3 切换到 OpenCV 4 会导致网络摄像头以最大 5 fps 的速度录制,而不是通常的 30 f
- 如何构建模板的显式实例化以提高编译速度?