zoukankan      html  css  js  c++  java
  • opencv中Mat格式的数据访问.at

    opencv3中图形存储基本为Mat格式,如果我们想获取像素点的灰度值或者RGB值,可以通过image.at<uchar>(i,j)的方式轻松获取。

    Mat类中的at方法对于获取图像矩阵某点的RGB值或者改变某点的值很方便,对于单通道的图像,则可以使用:

    image.at<uchar>(i, j)

    其中有一个要注意的地方是i对应的是点的y坐标,j对应的是点的x坐标,而不是我们习惯的(x,y)

    来获取或改变该点的值,而RGB通道的则可以使用:

        image.at<Vec3b>(i, j)[0]  
        image.at<Vec3b>(i, j)[1]  
        image.at<Vec3b>(i, j)[2]

    来分别获取B、G、R三个通道的对应的值。下边的代码实现对图像加椒盐噪声:

    // created by ning zhang 2018/4/25
    // The function of this program is to add noise to the image
    #include <opencv2/opencv.hpp>
    #include <iostream>

    using namespace std;
    using namespace cv;


    void salt_noise( Mat image, int time );

    int main ( int argc, char** argv )
    {
        Mat image = imread("../lena.jpg",0); //input the gray image
        if ( image.empty() )
        {
            cout << "Load image error" << endl;
            return -1;
        }
        salt_noise(image, 3000);
        namedWindow("image", 1);
        imshow("image", image);

        waitKey();
        return 0;
    }

    void salt_noise ( Mat image, int time )
    {
        for (int k = 0; k < time; k++ ) //time is the number of noise you add
        {
            int i = rand() % image.rows;
            int j = rand() % image.cols;
            if (image.channels() == 1) //single channel
            {
                image.at<uchar>(i,j) = rand() % 255;
            }
            else if (image.channels() == 3) //RGB channel
            {
                image.at<Vec3b>(i, j)[0] = rand() % 255;
                image.at<Vec3b>(i, j)[1] = rand() % 255;
                image.at<Vec3b>(i, j)[2] = rand() % 255;
            }
        }
    }

    效果图如下所示,可以为图片增加噪点

    代码地址:https://github.com/feifanrensheng/salt_noise

    还有比较省时的方法使用Mat的模板子类Mat_<T>,,对于单通道的具体使用:

    Mat_<uchar> img = image;  
    img(i, j) = rand() % 255;

    对于RGB通道的使用:

    Mat_<Vec3b> img = image;  
    img(i, j)[0] = rand() % 255;  
    img(i, j)[1] = rand() % 255;  
    mg(i, j)[2] = rand() % 255;

    还可以用指针的方法遍历每一像素:(耗时较小)

    void colorReduce(Mat image, int div = 64)  
        {  
            int nrow = image.rows;  
            int ncol = image.cols*image.channels();  
            for (int i = 0; i < nrow; i++)  
            {  
                uchar* data = image.ptr<uchar>(i);//get the address of row i;  
                for (int j = 0; j < ncol; j++)  
                {  
                    data[i] = (data[i] / div)*div ;  
                }  
            }  
        } 

    我们要尤其注意OpenCV坐标系与row&col的关系 (Mat::at(x,y)和Mat::at(Point(x, y))的区别)

    直接给出对应关系吧

    row == heigh == Point.y
    
    col == width == Point.x
    
    Mat::at(Point(x, y)) == Mat::at(y,x)

    因为还有点的坐标,所以建议在访问时都用Mat::at(Point(x, y))这种形式吧,免去了点坐标和行列的转换

    详细说明:

    1. 坐标体系中的零点坐标为图片的左上角,X轴为图像矩形的上面那条水平线;Y轴为图像矩形左边的那条垂直线。该坐标体系在诸如结构体Mat,Rect,Point中都是适用的。(虽然网上有学着说OpenCV中有些数据结构的坐标原点是在图片的左下角,但是我暂时还没碰到过)。

    2. 在使用image.at(x1, x2)来访问图像中点的值的时候,x1并不是图片中对应点的x轴坐标,而是图片中对应点的y坐标。因此其访问的结果其实是访问image图像中的Point(x2, x1)点,即与image.at(Point(x2, x1))效果相同。

    3. 如果所画图像是多通道的,比如说image图像的通道数时n,则使用Mat::at(x, y)时,其x的范围依旧是0到image的height,而y的取值范围则是0到image的width乘以n,因为这个时候是有n个通道,所以每个像素需要占有n列。但是如果在同样的情况下,使用Mat::at(point)来访问的话,则这时候可以不用考虑通道的个数,因为你要赋值给获取Mat::at(point)的值时,都不是一个数字,而是一个对应的n维向量。

    参考:https://blog.csdn.net/xiao_lxl/article/details/69568963

    https://blog.csdn.net/wangxuwen2/article/details/52443978

    https://blog.csdn.net/u013203733/article/details/73742247

    https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=baidu&wd=mat.at()&rsv_pq=ca3aed07000036c0&rsv_t=24317bhASyuKaxOgeSdlua%2FIqMWm7sRcP%2F1SQu5FhmelisfC2AWVqZaIMPk&rqlang=cn&rsv_enter=1&rsv_sug3=10&rsv_sug1=8&rsv_sug7=100&rsv_sug2=0&inputT=6442&rsv_sug4=7626

     

  • 相关阅读:
    Java RunTime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse. ......
    UVA 1597 Searching the Web
    UVA 1596 Bug Hunt
    UVA 230 Borrowers
    UVA 221 Urban Elevations
    UVA 814 The Letter Carrier's Rounds
    UVA 207 PGA Tour Prize Money
    UVA 1592 Database
    UVA 540 Team Queue
    UVA 12096 The SetStack Computer
  • 原文地址:https://www.cnblogs.com/feifanrensheng/p/8947185.html
Copyright © 2011-2022 走看看