zoukankan      html  css  js  c++  java
  • OpenCV -- <Vec3b>是什么

    一、What is vector?
    vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间的目的.
    用法:
    1.文件包含:
    首先在程序开头处加上#include以包含所需要的类文件vector,还有一定要加上using namespace std;
    2.声明一个int向量以替代一维的数组:vector a;(等于声明了一个int数组a[],大小没有指定,可以动态的向里面添加删除。
    比如Vec<uchar, 3>:
    其实这句就是定义一个uchar类型的数组,长度为3而已,例如 8U 类型的 RGB 彩色图像可以使用 ,3 通道 float 类型的矩阵可以使用 。对于 Vec 对象,可以使用[]符号如操作数组般读写其元素,如:Vec3b color; //用 color 变量描述一种 RGB 颜色:

    color[0]=255; //0通道的B 分量
    color[1]=0; //1通道的G 分量
    color[2]=0; //2通道的R 分量
    

    二、How do we use it ?

    • 先扩展一下访问像素的 .at 的用法:
      cv::mat的成员函数: .at(int y, int x)可以用来存取图像中对应坐标为(x,y)的元素坐标。但是在使用它时要注意,在编译期必须要已知图像的数据类型,这是因为cv::mat可以存放任意数据类型的元素。因此at方法的实现是用模板函数来实现的。假设提前已知一幅图像img的数据类型为 unsigned char型灰度图(单通道),要对坐标为(14,25)的像素重新赋值为25,则对应操作如下:
      srcImage.at(14,25) = 25;
      如果要操作的图片img是一幅数据类型同样为unsigned char的彩色图片,再次要求将坐标(14,25)的像素赋值为25。这个操作跟上面的就有点区别了,需要对这个像素三个通道的每个对应元素赋值,Opencv中图像三原色在内存中的排列顺序为B-G-R(见下面注释),操作过程如下:
      img.at(14,25) [0]= 25;//B
      img.at< Vec3b >(14,25) [1]= 25;//G
      img.at< Vec3b >(14,25 [2]= 25;//R

    一个简单小程序:

    #include <opencv2/opencv.hpp>
    #include <iostream>
    using namespace cv;
    using namespace std;
    int main()
    {
    Mat m(3, 3, CV_8UC3);//建立一个三行三列3通道像素
    Vec3b p;
    for (int i = 0; i < 3; i++)
    {
    	for (int j = 0; j < 3; j++)
    	{
    		p[0] = i;
    		p[1] = j;
    		p[2] = i+j;
    		m.at<Vec3b>(i,j) = p;
    	}
    }
    cout <<"数组:"<<endl<<"M= " << m << endl;
    int a = m.at<Vec3b>(2, 2)[2];
    Vec3b b = m.at<Vec3b>(2, 2)[2];
    cout << "访问一个数:" << a <<endl<<"访问三通道:"<<b<<endl;
    waitKey(0);
    return 0;
    

    }

    下面是网上的一个程序(在图片上实现椒盐噪声),椒盐噪声是一种特殊的噪点,是随机的将图像的部分像素设置为黑色或白色(其实我理解是把椒盐噪声点随机设置颜色)。
    经修改如下:

    #include<opencv2/opencv.hpp>
    #include<iostream>
    #include<cstdlib> 
    #include<vector>
    using namespace std;
    using namespace cv;
    
    #define WINDOW_1 "椒盐噪声点1"
    #define WINDOW_2 "椒盐噪声点2"
    void salt(Mat&, int);
    int main()
    {
    	Mat srcImage = imread("D://vvoo//lena.jpg");
    	Mat grayImage;
    	cvtColor(srcImage, grayImage/*, CV_8UC1*/, CV_RGB2GRAY);
    	imshow("原图", srcImage);
    
    	namedWindow(WINDOW_1, WINDOW_AUTOSIZE);
    	Mat g_dstImage = grayImage.clone();
    	Mat dstImage = srcImage.clone();
    	salt(g_dstImage, 3000);
    	salt(dstImage, 3000);
    
    	imshow(WINDOW_1, g_dstImage);
    	imshow(WINDOW_2, dstImage);
    	waitKey(0);
    	return 0;
    }
    void salt(Mat&dst, int Saltnum)
    {
    	int x,y;
    	for (int i = 0;i < Saltnum; i++)
    	{
    	    x = rand() % dst.cols;//保证x和y都在src的行数和列数范围内
    	    y = rand() %dst.rows;
    	    if (dst.channels() == 1)
    	    {
    		dst.at<uchar>(y, x) = 0;
    	    }
    	    if (dst.channels() ==3)
    	    {
    		dst.at<Vec3b>(y, x)[0] = 0;
    		dst.at<Vec3b>(y, x)[1] = 0;
    		dst.at<Vec3b>(y, x)[2] = 0;
               	    }
    	}
    
    
     }
    

    三、references
    1.http://blog.csdn.net/liukun321/article/details/38402601
    2.http://blog.csdn.net/wenhao_ir/article/details/50946638

  • 相关阅读:
    fastadmin中curd生成的表单将数字展示为文字
    fastadmin弹窗效果表单
    fastadmin 框架中图片点击放大
    linux vi 编辑文件常用快捷键
    mysql 数据库执行创建索引语句异常 Specified key was too long; max key length is 767 bytes
    eclipse 版本库信息存储错误,导致每次更新提交信息总弹出要输入账号密码问题 解决
    外国域名无法访问 metricbeat.docker.yml 无法下载问题解决
    ELK elasticsearch docker 多台服务器集群
    zipkin 服务跟踪
    多线程 采用spring线程池ThreadPoolTaskExecutor提高程序处理能力 笔记
  • 原文地址:https://www.cnblogs.com/zzzsj/p/14281267.html
Copyright © 2011-2022 走看看