opencv Mat 访问

OpenCV矩阵操作与遍历
该博客展示了如何使用OpenCV库对图像进行矩阵操作,包括将彩色图像转换为灰度,然后通过三种不同的方法遍历并修改矩阵元素:直接复制与修改、迭代器遍历和使用at函数。这些示例在理解和操作图像数据时非常有用。

 scan-c

    cv::Mat src = cv::imread(filePaths[0], cv::IMREAD_COLOR);

    cv::Mat gray;
    cv::cvtColor(src, gray, cv::COLOR_RGB2GRAY);

    //scan-c
    cv::Mat gray0(gray.clone());
    int nRows = gray0.rows;
    int nCols = gray0.cols * gray0.channels();

    if (gray0.isContinuous())
    {
        nCols = nCols * nRows;
        nRows = 1;
    }

    for (int row = 0; row < nRows; ++row)
    {
        uchar* p = gray0.ptr<uchar>(row);
        for (int col = 0; col < nCols; ++col)
        {
            p[col] = col % 255;
        }
    }

 scan-iterator

    //scan-iterator
    cv::Mat gray1(gray.clone());
    cv::MatIterator_<uchar> begin = gray1.begin<uchar>();
    cv::MatIterator_<uchar> end = gray1.end<uchar>();
    int k = 0;
    for (; begin != end; ++begin, ++k)
    {
        *begin = k % 255;
    }

    k = 0;
    cv::Mat src1 = src.clone();
    cv::MatIterator_<cv::Vec3b> begin3 = src1.begin<cv::Vec3b>();
    cv::MatIterator_<cv::Vec3b> end3 = src1.end<cv::Vec3b>();
    for (; begin3 != end3; ++begin3, ++k)
    {
        (*begin3)[0] = k % 255;
        (*begin3)[1] = k % 255;
        (*begin3)[2] = k % 255;
    }
    

 scan Vec3b

    //scan at
    k = 0;
    cv::Mat gray2 = gray.clone();
    for (int j = 0; j < gray2.rows; ++j)
    {
        for (int i = 0; i < gray2.cols; ++i)
        {
            gray2.at<uchar>(j, i) = k % 255;
            ++k;
        }
    }

    k = 0;
    cv::Mat src2 = src.clone();
    cv::Mat_<cv::Vec3b> _src2 = src2;
    for (int j = 0; j < src2.rows; ++j)
    {   
        for (int i = 0; i < src2.cols; ++i)
        {
            _src2(j, i).val[0] = k % 255;
            _src2(j, i)[1] = k % 255;
            _src2(j, i).val[2] = k % 255;

            ++k;
        }
    }

### OpenCV Mat 元素访问方法 在 OpenCV 中,`Mat` 是一种非常重要的数据结构,用于表示图像和矩阵。为了高效地访问 `Mat` 对象中的元素,OpenCV 提供了多种方法来实现这一点。 #### 使用指针访问 可以通过获取指向每一行的指针并手动遍历的方式来访问 `Mat` 的元素。这种方式适用于较大的矩阵或性能敏感的应用场景[^1]。 ```cpp #include <opencv2/opencv.hpp> using namespace cv; int main() { Mat mat = Mat::ones(3, 3, CV_8UC1); // 创建一个 3x3 单通道字节型矩阵 uchar* ptr = mat.ptr<uchar>(0); // 获取第 0 行的指针 for (int i = 0; i < mat.rows; ++i) { ptr = mat.ptr<uchar>(i); for (int j = 0; j < mat.cols; ++j) { std::cout << static_cast<int>(ptr[j]) << " "; // 访问每个元素 } std::cout << std::endl; } return 0; } ``` #### 使用 at 方法访问 对于更简单的应用场景,可以使用 `at<T>()` 函数直接访问指定位置上的元素。这种方法更加直观且易于理解。 ```cpp #include <opencv2/opencv.hpp> using namespace cv; int main() { Mat mat = Mat::eye(3, 3, CV_64F); // 创建一个 3x3 双精度浮点数单位矩阵 for (int i = 0; i < mat.rows; ++i) { for (int j = 0; j < mat.cols; ++j) { double value = mat.at<double>(i, j); // 使用 at 方法访问元素 std::cout << value << " "; } std::cout << std::endl; } return 0; } ``` #### 多通道矩阵的访问 当处理多通道矩阵(如 RGB 图像)时,需要特别注意通道顺序以及如何提取单个像素的信息。 ```cpp #include <opencv2/opencv.hpp> using namespace cv; int main() { Mat img = imread("example.png"); Vec3b pixel = img.at<Vec3b>(Point(10, 10)); // 获取坐标 (10, 10) 上的颜色值 std::cout << "B: " << (int)pixel[0] << ", G: " << (int)pixel[1] << ", R: " << (int)pixel[2] << std::endl; return 0; } ``` 以上展示了不同类型的矩阵及其对应的元素访问方式。无论是单通道还是多通道矩阵,都可以通过上述两种主要方式进行有效访问
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值