OpenCV学习笔记——2

库的一般使用方法

为了用 C++ 开发一个 OpenCV 应用,需要在代码中:

  1. 包含 OpenCV 的头文件定义;
  2. 链接 OpenCV 库(二进制文件),以获取最终的可执行文件

需要引入头文件来导入对应的模块,代码如下:

//在代码中包含所使用的每个模块的头文件
#include <opencv2/<module_name>/<module_name>.hpp>

要引入所有的模块用如下代码:

//在代码中包含所有的Opencv头文件
#include <opencv2/opencv.hpp>

OpenCV的API

Mat类

参考自
https://blog.csdn.net/maweifei/article/details/51221259

  • Mat不但是一个非常有用的图像容器类,同时也是一个通用的矩阵类

Mat 类是存储和操作 OpenCV 中图像的主要数据结构。这个类是在 core 模块中定义的。OpenCV 已经实现了对于这些数据结构自动分配和释放内存的机制。但是,当数据结构共享相同的缓冲存储器时,要特别注意

注意,OpenCV 中的许多函数在处理密集的单通道或多通道数组时,常使用 Mat 类。但是在某些场合,使用一个不同的数据类型可能很方便。例如,std::vector<>、Matx<>、Vec<> 或 Scalar。为此,OpenCV 提供了代理类 InputArray 和 OutputArray,允许前面的任意类型作为函数的参数使用。

Mat 类用于密集的 n 维单通道或多通道数组。实际上它可以存储实数或复数值向量和矩阵、彩色图像或灰度图像、直方图、点云等。

有许多种不同的方式可用来创建一个 Mat 对象,最流行的方法是构造函数,其数组的大小和类型被指定为:

Mat(nrows,ncols,type,fillValue)

数组元素的初始值可以由 Scalar 类设置为一个典型的四元素向量(对于存储在数组中的图像的每个 RGB 和透明度分量)。下面展示 Mat 的一个使用示例:

Mat img_A(4,4,CV_8U,Scalar(255));
//白色图像;
//具有 8 位无符号整数的 4x4 单个通道数组
//(最多 255 个值,对灰度图像有效,例如,255=白色)

DataType 类定义 OpenCV 的基本数据类型。基本数据类型可以是 bool、unsigned char、signed char、unsigned short、signed short、int、float、double 或者是以这些基本类型之一的值构成的一个元组(或称数组)。任何基本类型(Type)都可以用一个标识符以下面的形式定义:

CV_<bit depth>{U|S|F}C(<number of channels>)
  1. 在上面的代码中,U、S 和 F 分别代表 unsigned、signed 和 float 数据类型。(代表了图片的数据类型)
  2. bit depth代表了位数。(也就是指每一个像素点在内存空间所占的空间大小)

举个例子吧–比如说,如
如果你现在创建了一个存储–灰度图片的Mat对象,这个图像的大小为宽100,高100,那么,现在这张
灰度图片中有10000个像素点,它每一个像素点在内存空间所占的空间大小是8bite,8位–所以它对
应的就是CV_8

  1. C<number of channels>代表了图片的通道数

1–灰度图片–grayImg—是–单通道图像
2–RGB彩色图像---------是–3通道图像
3–带Alph通道的RGB图像–是--4通道图像

也就是说,CV_8U这个参数是表示图像的具体信息,组成,大小等
对于单通道数组,可应用下面的枚举类型,其数据类型的描述为:

enum{CV_8U=0,CV_8S=1,CV_16U=2,CV_16S=3,CV_32S=4,CV_32F=5,CV_64F=6};

需要注意的是,这三个声明是等价的:CV_8U、CV_8UC1 和 CV_8UC(1)。该单通道声明最适合于灰度图像的整型数组,然而一个数组的三通道声明更适合于具有三个分量(例如,RGB、BRG、HSV 等)的图像。对于线性代数运算,可以使用 float(F) 类型的数组。

Mat类中对象的创建

创建一个Mat对象的方法很多,我们现在先看一下Mat矩阵/图像容器类在OpenCv中的有关源代码:

1.使用Mat图像容器类创建Mat类的对象

//default constructor(构造默认对象)
Mat();

//! constructs 2D matrix of the specified size and type(构造2d矩阵,根据设定的大小,类型)
// (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
Mat(int rows, int cols, int type);
Mat(Size size, int type);

//! constucts 2D matrix and fills it with the specified value _s.(构造2d矩阵,填充特定值的颜色)
Mat(int rows, int cols, int type, const Scalar& s);
Mat(Size size, int type, const Scalar& s);

//! constructs n-dimensional matrix (构造n维矩阵)
Mat(int ndims, const int* sizes, int type);
Mat(int ndims, const int* sizes, int type, const Scalar& s);

2.使用Matlab风格的函数创建或者初始化Mat类的对象

//! Matlab-style matrix initialization
    static MatExpr zeros(int rows, int cols, int type);
    static MatExpr zeros(Size size, int type);
    static MatExpr zeros(int ndims, const int* sz, int type);
    static MatExpr ones(int rows, int cols, int type);
    static MatExpr ones(Size size, int type);
    static MatExpr ones(int ndims, const int* sz, int type);
    static MatExpr eye(int rows, int cols, int type);
    static MatExpr eye(Size size, int type);

从源码中我们可以发现,创建Mat矩阵/图像容器类的很多构造方法或者其他成员方法在创建Mat对象的时候,都
需要指定type所创建图像/矩阵的类型

OpenCV支持图像文件的的格式

OpenCV 支持最常见的图像格式。但是,某些图像格式需要(免费提供的)第三方类库。由 OpenCV 支持的主要格式有:

Windows bitmaps(*.bmp、*dib);
Portable image formats(*.pbm、*.pgm、*.ppm);
Sun rasters(*.sr、*.ras);
需要辅助库的格式有:
JPEG(*.jpeg、*.jpg、*.jpe);
JPEG 2000*.jp2);
Portable Network Graphics(*.png);
TIFF(*.tiff、*.tif);
WebP(*.webp);

对于 OpenCV 3.0 版本,除了上面列出的格式外,它还包含一个由地理数据抽象库(Geographic Data Abstraction Library,GDAL)所支持格式(NITF、DTED、SRTM等)的驱动器,通过 CMake 的选项 WITH_GDAL 来设置。注意,在 Windows OS 上,对 GDAL 的支持还没有经过广泛测试。

在 Windows 和 OS X 中,默认对这些格式(libjpeg、libjasper、libpng和libtiff)使用 OpenCV 附带的编解码器。之后,在这些操作系统中,可以读取 JPEG、PNG 和 TIFF 格式。Linux(和其他类 UNIX 开源操作系统)会寻找安装在系统中的编解码器。在 OpenCV 之前,可以安装编解码器或从 OpenCV 包中通过在 CMake 中设置正确的选项(例如,BUILD_JASPER、BUILD_JPEG、BUILD_PNG 和 BUILD_TIFF)来构建其他库。

简单代码

#include <iostream>
#include <opencv2/opencv.hpp>


using namespace std;
using namespace cv;

int main(int argc, char** argv)
{
    //String imageName("HappyFish.jpg"); // by default
    //if (argc > 1)
    //    imageName = argv[1];

    //Mat image = imread(samples::findFile(imageName), IMREAD_COLOR); // Read the file
    //if (image.empty()) {  // Check for invalid input
    //    cout << "Could not open or find the image" << endl;
    //    return -1;
    //}
    //namedWindow("Display window", WINDOW_AUTOSIZE); // Create a window for display.
    //imshow("Display window", image);                // Show our image inside it.
    //waitKey(0);   // Wait for a keystroke in the window

    Mat image2(512,512,CV_8UC1,255);//这里生成的是一个灰度图片
    
    if (image2.empty())
    {
        cout << "ERROR!";
        return -1;
    }
    namedWindow("Another window", WINDOW_AUTOSIZE);
    imshow("Another window", image2);
    waitKey(0);

    return 0;
}

代码解释:

Mat image2(512,512,CV_8UC1,Scalar(255));

是指创建一个大小为512x512的图形对象

namedWindow("Another window", WINDOW_AUTOSIZE);

是指给打开的窗口命名并规定大小

 imshow("Another window", image2);

将图像容器中的内容展示出来(display the image)

使用过程中遇到的问题

问题1
在这里插入图片描述
在这里插入图片描述
代码:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;


int mai22n()
{
	Mat im1, im2;
	
	const char win1[] = "Grabbing...", win2[] = "Recording...";
	double fps = 30.0;
	char file_out[] = "recorded.avi";
	VideoCapture cam(1);
	if (!cam.isOpened())
	{
		cout << "Error!";
		return -1;
	}
	int width = (int)cam.get(CAP_PROP_FRAME_WIDTH);
	int height = (int)cam.get(CAP_PROP_FRAME_HEIGHT);

	VideoWriter recVideo(file_out, VideoWriter::fourcc('M','S','V','C'), fps,Size(width,height));
	if (!recVideo.isOpened())
	{
		cout << "Error in record..";
		return -1;
	}
	namedWindow(win1);
	namedWindow(win2);
	
	while (1)
	{
		cam >> im1;
		cvtColor(im1, im2, COLOR_RGB2GRAY);
		
		imshow(win1, im1);
		imshow(win2, im2);
		if (waitKey(1000 / fps) >= 0)
		{
			break;
			
		}
	}
	cam.release();
	return 0;
}

解决:

问题2
在这里插入图片描述
解决:“生成”-》重新生成解决方案

问题3
openCV:解决图片显示闪退问题
转下面这篇博客

作者:aic1999
链接:https://blog.csdn.net/aic1999/article/details/83386584

注意:在VS中使用OpenCV时每次更换cpp文件要重新生成解决方案(“生成”-》重新生成解决方案)

发布了36 篇原创文章 · 获赞 6 · 访问量 2286

猜你喜欢

转载自blog.csdn.net/weixin_45709330/article/details/104376589