OpenCV:快速像素迭代
C++: OpenCV: fast pixel iteration
我正试图从流媒体网络摄像头图像中获得BGR值。我得到了内存访问冲突因为我没有在嵌套的for循环中正确使用指针但我不知道语法应该是什么。我找不到足够具体到我正在尝试做的看似基本的任务的文档。
除了解决内存访问冲突之外,我还希望能够在飞行中编辑每个像素,而不必进行深度复制,但不知道语法应该是什么。
这是我到目前为止的代码:
int main(int argc, char** argv)
{
int c;
Mat img;
VideoCapture capture(0);
namedWindow("mainWin", CV_WINDOW_AUTOSIZE);
bool readOk = true;
while (capture.isOpened()) {
readOk = capture.read(img);
// make sure we grabbed the frame successfully
if (!readOk) {
std::cout << "No frame" << std::endl;
break;
}
int nChannels = img.channels();
int nRows = img.rows;
int nCols = img.cols * nChannels;
if (img.isContinuous())
{
nCols *= nRows;
nRows = 1;
}
int i, j;
uchar r, g, b;
for (i = 0; i < nRows; ++i)
{
for (j = 0; j < nCols; ++j)
{
r = img.ptr<uchar>(i)[nChannels*j + 2];
g = img.ptr<uchar>(i)[nChannels*j + 1];
b = img.ptr<uchar>(i)[nChannels*j + 0];
}
}
if (!img.empty()) imshow("mainWin", img);
c = waitKey(10);
if (c == 27)
break;
}
}
您的扫描循环不正确。每一行应该只获得一次指向行的指针。由于像素是3字节的数量,因此最容易将它们视为Vec3b。
应该是
uchar r, g, b;
for (int i = 0; i < img.rows; ++i)
{
cv::Vec3b* pixel = img.ptr<cv::Vec3b>(i); // point to first pixel in row
for (int j = 0; j < img.cols; ++j)
{
r = pixel[j][2];
g = pixel[j][1];
b = pixel[j][0];
}
}
或
uchar r, g, b;
for (int i = 0; i < img.rows; ++i)
{
uchar* pixel = img.ptr<uchar>(i); // point to first color in row
for (int j = 0; j < img.cols; ++j)
{
b = *pixel++;
g = *pixel++;
r = *pixel++;
}
}
注意
使用Mat::at()
顺序访问像素是相当常见的,如:
// DON'T DO THIS!
uchar r, g, b;
for (int i = 0; i < img.rows; ++i)
{
for (int j = 0; j < img.cols; ++j)
{
cv::Vec3b pixel = img.at<cv::Vec3b>(i, j);
r = pixel[2];
g = pixel[1];
b = pixel[0];
}
}
然而,这样的用法是不合适的。对于每个像素访问,at()
需要通过将行号和行长度相乘来计算索引,并且在整个图像上计算会导致处理时间比上面的代码慢得多(其中ptr()
每行计算一次)。此外,在调试模式下,at()
有一个断言使它再次变得慢得多。
如果您确定行之间没有填充,则可以通过消除对ptr()
的调用来加快速度。在这种情况下,上面第二个循环中的像素指针将在每行结束后指向下一行的开始。但是,如果你的Mat是其他Mat感兴趣的区域,那就行不通了。
at()
是非常合适的。 相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 迭代时从向量和内存中删除对象
- 如何在c++迭代器类型中包装std::chrono
- 带过滤器的现代迭代c++集合
- 将迭代器从原始容器镜像到其副本
- 是否有一个很好的方法可以在C 11中打印出像JSON一样的Trie结构(仅迭代解决方案)的扁平命名空间
- 如何正确实现 -> 和 (*)。这样它们的行为就像 -> 和 (*)。在迭代器中
- 打开CV水彩色过滤器.(在图像的像素中迭代)
- 像迭代器一样编写 STL
- 如何制作更具表现力的 Python 迭代器?就像 C++ 迭代器一样
- 根据内核/掩码在相关的相邻像素之间有效地迭代
- 如何像 stl 迭代器一样"invalidate"对象
- 那么,是否可以像使用指针一样使用迭代器访问二维向量中的所有元素呢?
- OpenCV:快速像素迭代
- 为什么c++共享指针的行为不像迭代器的标准指针
- 如何使迭代器在迭代时表现得像一个类型
- 编写一个迭代器,使多个容器看起来像一个容器
- 我的向量结构没有像预期的那样迭代