C++ cvGet2D替代方案
我正在实时处理视频帧。我一次循环一个像素,做一些数学运算,然后将像素设置为特定的颜色(如果需要) 简而言之,我的算法如下所示:C++ cvGet2D替代方案,c++,c,image-processing,opencv,C++,C,Image Processing,Opencv,我正在实时处理视频帧。我一次循环一个像素,做一些数学运算,然后将像素设置为特定的颜色(如果需要) 简而言之,我的算法如下所示: //videoFrame is IplImage, 8 bit, 4 channel for(int i=0;i<videoFrame.width;i++){ for(int j=0;j<videoFrame.height;j++){ CvScalar pixel = cvGet2D(&v
//videoFrame is IplImage, 8 bit, 4 channel
for(int i=0;i<videoFrame.width;i++){
for(int j=0;j<videoFrame.height;j++){
CvScalar pixel = cvGet2D(&videoFrame, i, j);
double red = pixel.val[0];
double green = pixel.val[1];
double blue = pixel.val[2];
//do some math
if (someCondition) {
cvSet2D(&videoFrame, i, j, white);
}
}
}
//视频帧为IplImage,8位,4通道
对于(int i=0;i请尝试使用指针直接访问数据,如下所示
for(int i=0;i<videoFrame.width;i++){
for(int j=0;j<videoFrame.height;j++){
uchar B =((uchar *)(videoFrame.imageData + j*videoFrame.widthStep))[i*videoFrame.nChannels + 0];
uchar G =((uchar *)(videoFrame.imageData + j*videoFrame.widthStep))[i*videoFrame.nChannels + 1];
uchar R =((uchar *)(videoFrame.imageData + j*videoFrame.widthStep))[i*videoFrame.nChannels + 2];
//do some math
((uchar *)(videoFrame.imageData + j*videoFrame.widthStep))[i*videoFrame.nChannels + 0] = B;
((uchar *)(videoFrame.imageData + j*videoFrame.widthStep))[i*videoFrame.nChannels + 1] = G;
((uchar *)(videoFrame.imageData + j*videoFrame.widthStep))[i*videoFrame.nChannels + 2] = R;
}
}
for(int i=0;i尝试用指针直接访问数据,如下所示
for(int i=0;i<videoFrame.width;i++){
for(int j=0;j<videoFrame.height;j++){
uchar B =((uchar *)(videoFrame.imageData + j*videoFrame.widthStep))[i*videoFrame.nChannels + 0];
uchar G =((uchar *)(videoFrame.imageData + j*videoFrame.widthStep))[i*videoFrame.nChannels + 1];
uchar R =((uchar *)(videoFrame.imageData + j*videoFrame.widthStep))[i*videoFrame.nChannels + 2];
//do some math
((uchar *)(videoFrame.imageData + j*videoFrame.widthStep))[i*videoFrame.nChannels + 0] = B;
((uchar *)(videoFrame.imageData + j*videoFrame.widthStep))[i*videoFrame.nChannels + 1] = G;
((uchar *)(videoFrame.imageData + j*videoFrame.widthStep))[i*videoFrame.nChannels + 2] = R;
}
}
用于(int i=0;i除了johnlinvc的答案外,交换i
和j
的迭代可能是一个好主意,这样您就可以连续访问图像元素,因为OpenCV按行大顺序存储图像。除了johnlinvc的答案外,交换i
和j的迭代可能是一个好主意e> ,因此您可以连续访问图像元素,因为OpenCV按行的主要顺序存储图像。解决运行时查找效率低下的一般方法是将该查找移到编译时
定义像素迭代器模板。在循环之前,甚至在生成帧之前,获取与帧图像特征相对应的像素迭代器。然后使用该迭代器进行像素访问
大多数情况下,您可以使用纯顺序访问。请确保实现迭代器,以便逻辑顺序访问与原始字节级别的顺序访问相对应。这会有所帮助(而不是因为当前代码与不兼容)硬件的缓存策略。解决运行时查找效率低下的一般方法是将该查找移到编译时
定义像素迭代器模板。在循环之前,甚至在生成帧之前,获取与帧图像特征相对应的像素迭代器。然后使用该迭代器进行像素访问
大多数情况下,您可以使用纯顺序访问。请确保实现迭代器,以便逻辑顺序访问与原始字节级别的顺序访问相对应。这有助于(而不是因为当前代码不兼容)硬件的缓存策略。此处提供的答案
Etarion(对于新接口,使用Mat)和Andrew(对于IplImage,如您的案例)比johnlinvc提供的示例更干净、更快,因为它们消除了所有不必要的强制转换,并按行顺序访问像素,最大限度地减少了缓存未命中
它们适用于一般情况,甚至适用于感兴趣的区域(子矩阵)。这里提供的答案
Etarion(对于新接口,使用Mat)和Andrew(对于IplImage,如您的案例)比johnlinvc提供的示例更干净、更快,因为它们消除了所有不必要的强制转换,并按行顺序访问像素,最大限度地减少了缓存未命中
它们适用于一般情况,甚至适用于感兴趣的区域(子矩阵).谢谢您的输入,但这不起作用。B、G、R注册为“nan”或不是一个数字。对不起,我被您的双精度输入忽略了。如果IPL在每个通道中都有无符号8位整数,请将double更改为char应该起作用谢谢您的输入,但这不起作用。B、G、R注册为“nan”或不是数字。对不起,我被忽略了按双精度输入。如果IPL在每个通道中都有无符号8位整数,请将双精度更改为char。如果您更改了名称以包含冗余的“cheers”?您是认真的吗?您更改了名称以包含冗余的“cheers”?您是认真的吗?!