「OpenCV3.4」创建图像、像素遍历、像素显示、Vec4b、Vec3b、ptr、at、uchar

文章目录

    • 运行结果
    • 算法原理
    • Mat表示图像
    • 图像指针与矩阵格式转换:Mat转uchar*及uchar*转Mat代码实现
    • 编译文件
    • 源码详解
    • 指针访问像素
    • 生成透明图像

运行结果

「OpenCV3.4」创建图像、像素遍历、像素显示、Vec4b、Vec3b、ptr、at、uchar_第1张图片

算法原理

「OpenCV3.4」创建图像、像素遍历、像素显示、Vec4b、Vec3b、ptr、at、uchar_第2张图片
图中红点的坐标是(2,1) 还是 (1,2)答案是(2,1)!为什么? 看清了 我问的是坐标!!不是行列!!
那么(2,1) 和 (1,2)究竟有什么不同?
(2,1)表示的是红点的坐标,就是红点的 x 坐标是 2, y 坐标是 1。
(1,2)表示的是红点的行和列,就是红点的行是1,列是2,也就是红点在第 1 行,第 2 列。

这下子我相信大家都明白这两者的区别了吧!

Mat表示图像

「OpenCV3.4」创建图像、像素遍历、像素显示、Vec4b、Vec3b、ptr、at、uchar_第3张图片

//---------------------------------【头文件、命名空间包含部分】---------------------------
//          描述:包含程序所使用的头文件和命名空间
//-----------------------------------------------------------------------------------------------
#include "opencv2/core/core.hpp"
#include 
using namespace std;
using namespace cv;

//--------------------------------------【main( )函数】-----------------------------------------
//          描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//-----------------------------------------------------------------------------------------------
int main(int,char**){

    Mat I = Mat::eye(4, 4, CV_64F);
    I.at<double>(1,1) = CV_PI;
    cout << "\nI\n" << I << endl;

    Mat r = Mat(5, 3, CV_8UC3);
    randu(r, Scalar::all(0), Scalar::all(255));

    cout << "r\n" << r << endl << endl;

    Point2f p(6, 2);
    cout << "【2维点】p = " << p << ";\n" << endl;

    Point3f p3f(8, 2, 0);
    cout << "【3维点】p3f = " << p3f << ";\n" << endl;

    vector<float> v;
    v.push_back(3);
    v.push_back(5);
    v.push_back(7);

    cout << "【基于Mat的vector】shortvec = \n" << Mat(v) << ";\n"<<endl;

    vector<Point2f> points(10);
    for (size_t i = 0; i < points.size(); ++i)
        points[i] = Point2f((float)(i * 5), (float)(i % 7));

    cout << "【二维点向量】points = \n" << points<<";";


    return 0;
}


下面说一下如何显示像素

srcImage.at(j, i)
srcImage.at(Point(j, i))

opencv灰度图mat.at(i, j)显示不出来会乱码,如果你也是单通道灰度图的话,和我一样的情况的话,记得转成int(mat.at(i, j))

指针法读写像素
读写一个灰度图像GRAY像素点的像素值Scalar intensity = Mat.at(y,x)
读写一个RGB彩色像素点的像素值
浮点型:

float blue = srcImage.at<Vec3b>(row, col)[0]//获得蓝色通道b 的像素值
float green = srcImage.at<Vec3b>(row, col)[1];   //获得绿色通道g的像素值
float red = srcImage.at<Vec3b>(row, col)[2];       //获得红色通道r的像素值

整型:

int blue = srcImage.at<Vec3b>(row, col)[0];   //获得蓝色通道b 的像素值
int green  = srcImage.at<Vec3b>(row, col)[1];  //获得绿色通道g的像素值
int red  = srcImage.at<Vec3b>(row, col)[2];   //获得红色通道r的像素值

单通道(灰度图)

int ROWS = 100; // height
int COLS = 200; // width
Mat img1(ROWS , COLS , CV_32FC1);  
for (int i=0; i<ROWS ; i++)  
{  
    for (int j=0; j<COLS ; j++)  
    {  
        img1.at<float>(i,j) = 3.2f;  
    }  
}

type的类型具体要看Mat对象的通道数据类型:

Mat_<uchar>---------CV_8U
Mat<char>-----------CV_8S
Nat_<short>---------CV_16S
Mat_<ushort>--------CV_16U
Mat_<int>-----------CV_32S
Mat_<float>----------CV_32F
Mat_<double>--------CV_64F

三通道(彩色图)

int ROWS = 100; // height
int COLS = 200; // width
Mat img1(ROWS , COLS , CV_8UC3);  
  
for (int i=0; i<ROWS ; i++)  
{  
    for (int j=0; j<COLS ; j++)  
    {  
       img1.at<vec3b>(i,j)[0]= 3.2f;  // B 通道
       img1.at<vec3b>(i,j)[1]= 3.2f;  // G 通道
       img1.at<vec3b>(i,j)[2]= 3.2f;  // R 通道
    }  
}

图像指针与矩阵格式转换:Mat转uchar及uchar转Mat代码实现

RGB3通道图像Mat转uchar及uchar转Mat,编程环境:opencv2.4.13 ,
由于OpenCV读入和显示都是BGR类型,本文显示图像也用的BGR格式,若需换成RGB,程序中有对应替换程序。
先说一下要用到的Vec3b类型:
对于彩色图像中的一行,每列中有3个uchar元素,这可以被认为是一个小的包含uchar元素的vector,在OpenCV中用 Vec3b 来命名。

//Vec---是一个OpenCv的---向量类模板(向量模板类)
//Vec---向量类模板的类模板原型:
template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1>
//实例化:
typedef Vec<uchar, 3> Vec3b;
//Vec3b---表示每一个Vec3b对象中,可以存储3个char(字符型)数据,比如可以用这样的对象,去存储RGB图像中的一个像素点
//Vec3b使用:
//描述一种RGB颜色:
Vec3b color;
color[0]=0;//B分量
color[1]=0;//G分量
color[2]=255;//R分量

#include 

using namespace std;
using namespace cv;

/**将Mat类型的数据转换为uchar类型*/
uchar* matToUchar(Mat img)
{
	int img_width = img.cols;
	int img_height = img.rows;
	uchar *p1=(uchar*)malloc(sizeof(uchar)*img_height*img_width*3);/*[img_width * img_height * 3]*/
	for (int i = 0; i < img_width * img_height * 3; i++)
	{
		p1[i] = (uchar)img.at<Vec3b>(i / (img_width * 3), (i % (img_width * 3)) / 3)[i % 3];
	}
	return p1;
}

/**将uchar类型的数据转换为Mat类型*/
int ucharToMat(uchar *p2,Mat& src,int flag)
{
	int img_width = src.cols;
	int img_height = src.rows;
	//Mat img(Size(img_width, img_height), CV_8UC3);
	for (int i = 0; i < img_width * img_height * 3; i++)
	{
		src.at<Vec3b>(i / (img_width * 3), (i % (img_width * 3)) / 3)[i % 3] = p2[i];//BGR格式
		//src.at(i / (img_width * 3), (i % (img_width * 3)) / 3)[i % 3] = p2[i];//换为RGB使用
	}
	flag = 1;
	return flag;
}

int main()
{
	Mat img = imread("01.jpg", 1);
	uchar* img_p = matToUchar(img);
	int img_height = img.rows;
	int img_width = img.cols;
	Mat view(img_height, img_width, CV_8UC3, Scalar(0, 0, 0));
	int flag_ucharTomat = ucharToMat(img_p, view, 0);
	if (flag_ucharTomat)
	{
		printf("图片格式转换成功!");
	}
	cvNamedWindow("Image view", 0);
	imshow("Image view", view);
	cvWaitKey(0);
	cvDestroyWindow("Image view");
}

编译文件

cmake_minimum_required(VERSION 2.8)
project(imageBasics)
set(CMAKE_BUILD_TYPE "Debug")
# 添加c++ 11标准支持
set(CMAKE_CXX_FLAGS "-std=c++11 -O2")

# 寻找OpenCV库
find_package(OpenCV REQUIRED)

add_executable(a_basis a_basis.cpp)
target_link_libraries(a_basis ${OpenCV_LIBS})

源码详解

#include 
#include 
#include 
#include 
#include 

int main(int argc, char **argv) {
  // 本教程通过创建二维三通道图像,创建带alpha通道的透明图像和读取图像来讲解图像的维度,通道,深度,类型,四种遍历方式等相关内容
  /*****************************************************************************
  * 创建一张二维三通道图像
  *****************************************************************************/
  cv::Mat q_image(674, 1200, CV_8UC3, cv::Scalar(0,0,255));
  /**
   * cv::Mat定义一个矩阵行数/高为image.rows,列数/宽为image.cols
   * CV_(位数)+(数据类型)+(通道数)
   * 其中CV_后面紧接的数字表示位数,分别对应8bit,16bit
   * U表示Unsigned无符号整数类型,即其内部元素的值不可以为负数
   * S表示Signed有符号整数类型,其值存在负数
   * F则表示浮点数类型,即矩阵的内部元素值可以为小数(32对应单精度float类型,64对应双精度double类型)
   * C1~C4表示对应的通道数,即有1~4个通道
   *
   *【1】CV_8UC1---可以创建---8位无符号的单通道---灰度图片---grayImg
   * #define CV_8UC1 CV_MAKETYPE(CV_8U,1)  type 预定义的常量 = 0
   *
   *【2】CV_8UC3---可以创建---8位无符号的三通道---RGB彩色图像---colorImg
   * #define CV_8UC3 CV_MAKETYPE(CV_8U,3)  type 预定义的常量 = 16
   *
   *【3】CV_8UC4---可以创建---8位无符号的四通道---带透明色Alpha通道的RGB图像
   * #define CV_8UC4 CV_MAKETYPE(CV_8U,4)  type 预定义的常量 = 24
   *
   * cv::Scalar(0,0,255)每个像素由三个元素组成即三通道,初始化颜色值为(0,0,255)
   *
  */
  std::cout << "q_image.rows: " << q_image.rows << std::endl; // 674
  std::cout << "q_image.cols: " << q_image.cols << std::endl; // 1200
  std::cout << "q_image.dims: " << q_image.dims << std::endl; // 2
  std::cout << "q_image.channels(): " << q_image.channels() << std::endl; // 3
  std::cout << "q_image.type(): " << q_image.type() << std::endl; // 16
  /**
   * 类型表示了矩阵中元素的类型以及矩阵的通道个数
   * 它是一系列的预定义的常量,其命名规则为CV_(位数)+(数据类型)+(通道数)
   * CV_8UC3 = 16 , CV_16UC3 = 18
   */
  std::cout << "q_image.depth(): " << q_image.depth() << std::endl; // 0
  // depth用来度量每一个像素中每一个通道的精度,但它本身与图像的通道数无关,depth数值越大精度越高
  // Opencv中,Mat.depth()得到的是一个0~6的数字,分别代表不同的位数
  // 对应关系如下: enum{CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6}
  // 可见0和1都代表8位,2和3都代表16位,4和5代表32位,6代表64位
  // 其中U是unsigned无符号数的意思,S表示signed有符号数的意思
  std::cout << "q_image.elemSize(): " << q_image.elemSize() << std::endl; // 3(通道)
  // 矩阵中元素的个数为image.rows*image.cols=674*1200
  // elemSize以8位(一个字节)为单位表示矩阵中每一个元素的字节数
  // 数据类型是CV_8UC1,elemSize==1
  // 数据类型是CV_8UC3或CV_8SC3,elemSize==3
  // 数据类型是CV_16UC3或CV_16SC3,elemSize==6
  std::cout << "q_image.elemSize1(): " << q_image.elemSize1() << std::endl; // 1(字节)
  // elemSize加上一个"1"构成了elemSize1这个属性,可认为是元素内1个通道的意思
  // 表示Mat矩阵中每一个元素单个通道的数据大小,以字节为单位,所以eleSize1==elemSize/channels
  std::cout << "q_image.step: " << q_image.step << std::endl; // 3600
  // step可以理解为Mat矩阵中每一行的"步长",以字节为单位,step=elemSize()*cols=3*1200=3600
  // 每一行中所有元素的字节总量,累计了一行中所有元素,所有通道,所有通道的elemSize1之后的值
  cv::namedWindow( "q_image", CV_WINDOW_AUTOSIZE );
  imshow( "q_image", q_image);
  cv::waitKey(0);


  /*****************************************************************************
  * 创建一张alpha通道的Mat图像
  *****************************************************************************/
  cv::Mat mat(480, 640, CV_8UC4);//创建带alpha通道的Mat
    for(int i = 0; i < mat.rows; ++i) {
    for(int j = 0; j < mat.cols; ++j) {
      auto &rgba = mat.at<cv::Vec4b>(i, j);
      /**
       * OpenCV源代码中的定义 typedef Vec  Vec2b
       * Vec2b 表示每个Vec2b对象可以存储2个char(字符型)数据
       * vec3b 表示每个Vec3b对象可以存储3个char(字符型)数据,比如可以用这样的对象,去存储RGB图像中的
       * vec4b 表示每个Vec4b对象可以存储4个字符型数据,可以用这样的类对象去存储—4通道RGB+Alpha的图
       * mat.at(i, j);
    * 从mat中取出一个像素,像素的类型是Vec4b该类型含义是,有4个UCHAR类型的元素
    * 其中rgba[0],rgba[1],rgba[2]代表像素三原色BGR,即为蓝色Blue,Green绿色,红色Red,rgba[3]代表像素的Alpha值表示像素透明度
       */
      rgba[0]= UCHAR_MAX;
      rgba[1]= cv::saturate_cast<uchar>((float (mat.cols - j)) / ((float)mat.cols) *UCHAR_MAX);
      rgba[2]= cv::saturate_cast<uchar>((float (mat.rows - i)) / ((float)mat.rows) *UCHAR_MAX);
      rgba[3]= cv::saturate_cast<uchar>(0.5 * (rgba[1] + rgba[2]));
    }
  }
  imshow("带alpha通道的图像",mat);
  cv::waitKey(0);


  /*****************************************************************************
   * 读取一张二维三通道图像
   *****************************************************************************/
  cv::Mat image;
  image = cv::imread("../ubuntu.png", -1);// 新版本OpenCV中引入Mat类自动管理内存处理图像数据 读入一张图片
  /**
   * CV_LOAD_IMAGE_UNCHANGED = flag = -1  8位深度  原通道 按照图像原样读取 保留Alpha通道(第4通道)
   * CV_LOAD_IMAGE_GRAYSCALE = flag = 0   8位深度  1通道  将图像转成单通道灰度图像后读取
   * CV_LOAD_IMAGE_COLOR = flag = 1       8位深度  3通道  将图像转换成3通道BGR彩色图像
   */
  if (image.data == nullptr) {
    std::cerr << "文件不存在." << std::endl;// 判断图像文件是否正确读取如果不能读取可能是文件不存在
    return 0;// 没有读取图片return 0终止函数
  }
  cv::namedWindow( "image", CV_WINDOW_AUTOSIZE );// OpenCV创建显示图像窗口"image"
  imshow( "image", image);// 在窗口"image"显示图像image
  cv::waitKey(0);// 等待任意按键按下退出,不加这一句窗口会一闪而过,等待6000 ms后窗口自动关闭 waitKey(6000);
  std::cout << "image.rows: " << image.rows << std::endl;// image.rows图像的行数是: 674 是高度
  std::cout << "image.cols: " << image.cols << std::endl;// image.cols图像的列数是: 1200 是宽度 1200*674
  std::cout << "image.dims: " << image.dims << std::endl;// image.dims图像的维度是: 2
  std::cout << "image.channels(): " << image.channels() << std::endl;// image.channels()图像的通道是: 3
  std::cout << "image.type(): " << image.type() << std::endl;// image.type()图像的类型是: 16
  std::cout << "image.depth(): " << image.depth() << std::endl;// image.depth()图像的深度是: 0
  std::cout << "image.elemSize(): " << image.elemSize() << std::endl;// image.elemSize()图像的elemSize是: 3
  std::cout << "image.elemSize1(): " << image.elemSize1() << std::endl;// image.elemSize1()图像的elemSize1是: 1

  cv::Mat gray_image;
  cv::cvtColor(image, gray_image, cv::COLOR_BGR2GRAY);// 转换为灰度图像
  imshow( "gray_image", gray_image);// 在窗口"gray_image"显示图像gray_image
  cv::waitKey(0);// 按任意键退出,不加这一句窗口会一闪而过
  std::cout << "gray_image.rows: " << gray_image.rows << std::endl;// gray_image.rows图像的行数是: 674
  std::cout << "gray_image.cols: " << gray_image.cols << std::endl;// gray_image.cols图像的列数是: 1200
  std::cout << "gray_image.dims: " << gray_image.dims << std::endl;// gray_image.dims图像的维度是: 2
  std::cout << "gray_image.channels(): " << gray_image.channels() << std::endl;// gray_image.channels()图像的通道是: 1
  std::cout << "gray_image.type(): " << gray_image.type() << std::endl;// gray_image.type()图像的类型是: 0
  std::cout << "gray_image.depth(): " << gray_image.depth() << std::endl;// gray_image.depth()图像的深度是: 0
  std::cout << "gray_image.elemSize(): " << gray_image.elemSize() << std::endl;// gray_image.elemSize()图像的elemSize是: 1
  std::cout << "gray_image.elemSize1(): " << gray_image.elemSize1() << std::endl;// gray_image.elemSize1()图像的elemSize1是: 1

  /*****************************************************************************
   * 常用Mat类矩阵元素读取方式有:通过at方法进行读取,通过指针ptr进行读取,通过迭代器进行读取,
   * 通过矩阵元素的地址定位方式进行读取,接下来将详细的介绍这四种读取方式.
   *****************************************************************************/
  // 通过at方法读取单通道Mat矩阵类中的元素
  cv::Mat M4 = (cv::Mat_<double>(3, 3) << 0, -1, 0, -1, 0, 0, 0, 0, 1);
  // 创建自定义数据的矩阵Mat
  std::cout << "M4 = " << std::endl << M4 << std::endl;
  double value = M4.at<double>(0,1); // -1
  // 通过at方法读取元素需要在后面跟上<数据类型>以坐标的形式给出需要读取的元素坐标(行数,列数)
  std::cout << "value = " << value << std::endl;

  // at 方法读取三通道Mat矩阵类中的元素
  /**
   * Mat类中获取或改变该像素点的灰度值或者RGB值,可以通过image.at(i,j)的方式。
   * 单通道图像image.at(i, j) i对应的是点的y坐标,j对应的是点的x坐标,而不是我们习惯的(x,y)
   * RGB
   * image.at(i, j)[0]
   * image.at(i, j)[1]
   * image.at(i, j)[2]
   */
  cv::Mat M5(3, 4, CV_8UC3, cv::Scalar(0, 0, 255));
  // 读取彩色图像像素
  for(int i = 0;i < M5.rows;i++){
    for(int j = 0;j < M5.cols;j++){
      std::cout << "M5.at(i,j)[0]: " << int(M5.at<cv::Vec3b>(i,j)[0]) << std::endl;  //蓝色通道
      std::cout << "M5.at(i,j)[0]: " << int(M5.at<cv::Vec3b>(i,j)[1]) << std::endl;  //绿色通道
      std::cout << "M5.at(i,j)[0]: " << int(M5.at<cv::Vec3b>(i,j)[2]) << std::endl;  //红是通道
      // 通过at方法读取多通道Mat矩阵类中的元素,多通道矩阵每一个元素坐标处都是多个数据,因此引入一个变量用于表示同一元素多个数据
      // OpenCV中定义cv::Vec3b,cv::Vec3s,cv::Vec3w,cv::Vec3d,cv::Vec3f,cv::Vec3i六种类型表示同一个元素的三个通道数据
      // 数字表示通道的个数,最后一位是数据类型的缩写,b是uchar类型的缩写,s是short类型的缩写,w是ushort类型的缩写,
      // d是double类型的缩写,f是float类型的缩写,i是int类型的缩写
    }
  }

  // 通过指针ptr读取Mat类矩阵中的元素
  cv::Mat M6(3, 4, CV_8UC3, cv::Scalar(0, 0, 1));
  for (int i = 0; i < M6.rows; i++){
    // 循环遍历图像的每一行
    uchar* row_ptr = M5.ptr(i);
    // 用cv::Mat::ptr获得图像的行头指针,再定义一个uchar类型的row_ptr指向第i行的头指针
    for (int j = 0; j < M6.cols*M6.channels(); j++){
      // 循环遍历图像矩阵中每一行所有通道的数据
      // Mat类矩阵矩阵中每一行中的每个元素都是挨着存放,每一行中存储的数据数量为列数与通道数的乘积
      // 即代码中指针向后移动cols*channels()-1位,当读取第2行数据中第3个数据时,可以直接用M6.ptr(1)[2]访问
      std::cout << "row_ptr[" << j << "]: " << (int)row_ptr[j] << std::endl;
      // 循环输出每一个通道中的数值
    }
  }


  // 通过迭代器访问Mat类矩阵中的元素
  // Mat类变量同时也是一个容器变量,所以Mat类变量拥有迭代器,用于访问Mat类变量中的数据,通过迭代器可以实现对矩阵中每一个元素的遍历
  cv::Mat M7(3, 4, CV_8UC3, cv::Scalar(0, 1, 2));
  cv::MatIterator_<uchar> it = M7.begin<uchar>();
  // 初始位置的迭代器
  cv::MatIterator_<uchar> it_end = M7.end<uchar>();
  // 终止位置的迭代器
  // Mat类的迭代器变量类型是cv::MatIterator_< >,在定义时同样需要在括号中声明数据的变量类型
  // Mat类迭代器的起始是Mat.begin< >(),结束是Mat.end< >(),与其他迭代器用法相同,通过"++"运算实现指针位置向下迭代
  // 数据的读取方式是先读取第一个元素的每一个通道,之后再读取第二个元素的每一个通道,直到最后一个元素的最后一个通道
  for(; it != it_end; it++){
    std::cout << (int)(*it) << " ";
    std::cout << std::endl;
  }
  cv::destroyAllWindows();
  return 0;
}

指针访问像素

#include 
#include 
using namespace std;
using namespace cv;

void colorReduce(Mat& inputImage, Mat& outputImage, int div);

int main( )
{
    Mat srcImage = imread("../11.jpg");
    imshow("11",srcImage);
    Mat dstImage;
    dstImage.create(srcImage.rows,srcImage.cols,srcImage.type());
    colorReduce(srcImage,dstImage,32);


    imshow("22",dstImage);
    imwrite("../dstImage.png",dstImage);
    waitKey(0);
}


void colorReduce(Mat& inputImage, Mat& outputImage, int div)
{
    outputImage = inputImage.clone();
    int rowNumber = outputImage.rows;
    int colNumber = outputImage.cols*outputImage.channels();

    for(int i = 0;i < rowNumber;i++)
    {
        uchar* data = outputImage.ptr<uchar>(i);
        for(int j = 0;j < colNumber;j++)
        {
            data[j] = data[j]/div*div + div/2;
        }
    }
}

生成透明图像

「OpenCV3.4」创建图像、像素遍历、像素显示、Vec4b、Vec3b、ptr、at、uchar_第4张图片


#include  //头文件
#include 
#include 
using namespace cv; //包含cv命名空间

void createAlphaMat(Mat &mat)
{
    for(int i = 0; i < mat.rows; ++i) {
        for(int j = 0; j < mat.cols; ++j) {
            Vec4b&rgba = mat.at<Vec4b>(i, j);
            rgba[0]= UCHAR_MAX;
            rgba[1]= saturate_cast<uchar>((float (mat.cols - j)) / ((float)mat.cols) *UCHAR_MAX);
            rgba[2]= saturate_cast<uchar>((float (mat.rows - i)) / ((float)mat.rows) *UCHAR_MAX);
            rgba[3]= saturate_cast<uchar>(0.5 * (rgba[1] + rgba[2]));
        }
    }
}


int main( )
{
    // 【1】读入一张图片,载入图像
    Mat srcImage = imread("../1.jpg");
    // 【2】显示载入的图片
    imshow("【原始图】",srcImage);

    //进行腐蚀操作
    Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
    Mat dstImage;
    erode(srcImage, dstImage, element);
    //显示效果图
    imshow("【效果图】腐蚀操作", dstImage);
    imwrite("../腐蚀.png",dstImage);


    //【3】进行均值滤波操作
    blur( srcImage, dstImage, Size(7, 7));

    //【4】显示效果图
    imshow( "均值滤波【效果图】" ,dstImage );
    imwrite("../模糊.png",dstImage);

    Mat edge,grayImage;	//参数定义
    //【1】创建与src同类型和大小的矩阵(dst)
    dstImage.create( srcImage.size(), srcImage.type() );
    //【2】将原图像转换为灰度图像
    cvtColor( srcImage, grayImage, COLOR_BGR2GRAY );

    //【3】先用使用 3x3内核来降噪
    blur( grayImage, edge, Size(3,3) );

    //【4】运行Canny算子
    Canny( edge, edge, 3, 9,3 );

    //【5】显示效果图
    imshow("【效果图】Canny边缘检测", edge);
    imwrite("../边缘检测.png", edge);

    //创建带alpha通道的Mat
    Mat mat(480, 640, CV_8UC4);
    createAlphaMat(mat);
    imwrite("../透明Alpha值图.png", mat);
    imshow("生成的png图",mat);


    // 【3】等待任意按键按下
    //  waitKey(0);
    // 【3】等待6000 ms后窗口自动关闭
    waitKey(1000);
    return 0;
}




你可能感兴趣的:(从零开始学习SLAM,OpenCV3.4)