zoukankan      html  css  js  c++  java
  • Mat数据类型

    https://www.cnblogs.com/feifanrensheng/p/8947185.html

    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

  • 相关阅读:
    Spark Streaming Programming Guide
    Apache Kafka Replication Design – High level
    Apache Kafka源码分析 – Log Management
    Apache Kafka源码分析 – Broker Server
    Big Data资料汇总
    Spark 源码分析 -- task实际执行过程
    Spark源码分析 – 汇总索引
    Spark源码分析 – Shuffle
    C# Windows form application 播放小视频
    leetcode第一刷_Sudoku Solver
  • 原文地址:https://www.cnblogs.com/Manuel/p/14340115.html
Copyright © 2011-2022 走看看