【OpenCV_03】图像载入,显示和输出 Read & Display Image

来源:互联网 发布:ps大小尺寸怎么调整mac 编辑:程序博客网 时间:2024/04/29 21:28

图像的载入,显示和输出


这篇博客我回谈一谈,如何通过采用OpenCV的库函数将图像载入,显示以及输出。首先,打开C++的IDE编程环境新建一个工程,(必须把OpenCV的环境设置好在IDE下)


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#include "opencv2/highgui/highgui.hpp"#include <iostream>using namespace cv;using namespace std;int main( int argc, const char** argv ){     Mat img = imread("MyPic.JPG", CV_LOAD_IMAGE_UNCHANGED);   //read the image data in the file "MyPic.JPG" and store it in 'img'     if (img.empty()) //check whether the image is loaded or not     {          cout << "Error : Image cannot be loaded..!!" << endl;          //system("pause"); //wait for a key press          return -1;     }     namedWindow("MyWindow", CV_WINDOW_AUTOSIZE);       //create a window with the name "MyWindow"     imshow("MyWindow", img);      //display the image which is stored in the 'img' in the "MyWindow" window     waitKey(0); //wait infinite time for a keypress     destroyWindow("MyWindow"); //destroy the window with the name, "MyWindow"     return 0;}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



在运行程序之前,在C++源文件文件夹里放一个叫 (MyPic.JPG) 文件名的图片,否则就需要设置函数imread()的第一个参数为图片的绝对路径。 

代码解释
  • #include "stdafx.h"
因为是在 Visual Studio下开发,所以需要加上。
  • #include "opencv2/highgui/highgui.hpp"
imread()namedWindow()imshow() and waitKey() 的定义需要包含以上头文件。上面定义的Mat类的对象,在头文件 "opencv2/core/core.hpp"已经声明。 It is declared in "opencv2/core/core.hpp" header file. 但是代码中为什么没有?因为在"opencv2/highgui/highgui.hpp" 头文件已经包含了,所以不需要再包含一次了。
  • using namespace cv;
所有的数据结构和函数都在 "opencv2/core/core.hpp" 及 "opencv2/highgui/highgui.hpp"声明在cv的命名空间里。所以在include头文件后面添加
using namespace cv;
或者每个OpenCV函数和数据前面加 'cv::'  (e.g - cv::Mat, cv::imread() , etc)。

  • '#include <iostream>' 及 'using namespace std'由于在代码里用到了 'cout' 输出字符串,这是C++语法里需要熟悉的。

  • Mat img = imread(const string& filename, int flags=CV_LOAD_IMAGE_COLOR)
Mat 是以矩阵存储图片的数据结构,在 "opencv2/core/core.hpp"头文件里声明。

imread()函数声明在"opencv2/highgui/highgui.hpp"头文件. 从文件里载入图片并且存入Mat的数据结构中。

imread() 函数的参数
  • filename - 图片路径,如果仅给给出名字,那么需要和C++源文件在同一个文件夹下,否则就得给出绝对路径。
  • flags - 有4种可能的输入
    • CV_LOAD_IMAGE_UNCHANGED - image-depth=8 bits per pixel in each channel,  no. of channels=unchanged 
    • CV_LOAD_IMAGE_GRAYSCALE - image depth=8 bits,  no. of channels=1
    • CV_LOAD_IMAGE_COLOR - image-depth=?,  no. of channels=3
    • CV_LOAD_IMAGE_ANYDEPTH - image-depth=unchanged ,  no. of channels=?
    • CV_LOAD_IMAGE_ANYCOLOR - image-depth=?,  no. of channels=unchanged 
也可以把上面的参数组合起来
e.g -
CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR - image-depth=unchanged,  no. of channels=unchanged 
CV_LOAD_IMAGE_COLOR | CV_LOAD_IMAGE_ANYDEPTH - image-depth=unchanged,  no. of channels=3

如果不清楚需要什么样的数据结构, 采用 CV_LOAD_IMAGE_COLOR作为函数 imread() 的第2个参数。


为了理解位深以及通道的概念,需要了解图像处理的部分知识,下面简单介绍一个图像处理。

每个数字图像都是由像素构成的,每个像素都是有一定值的。像素的最小值为0代表黑色,随着像素值增加,像素的亮度也随着增加。在计算机内存里,十进制表示的255表示白色。每个像素都有一个固定值的bits。像素的最大值可以是255,(即11111111二进制)。

位深又是什么呢?位深意思是每个像素值的比特数。如果位深为8,那么每个像素可以表示的值为0~255,如果是4,那么就是0~15 (即1111二进制)。 

举个简单的例子,位深为8比特的图,每个表格代表一个像素,那么每个像素的值为0~255。

下面是此图的参数.
  •  位深为 8 bit
  • 1 channel (灰度图 )
  • 高为4个像素 
  • 宽为5个像素
  • 图像分辨率为 4x5.
灰度图,如果像素值高,就会比较亮,如果像素值低,就会比较暗。

Grayscale Image with image depth of 8Grayscale Image with image depth of 8


下面介绍一个简单的模型是彩色图像。彩色 图像含有至少三个通道,Red, Green and Blue.任何颜色都可以由这三原色构成,所以说任何一个像素都是RGB三色的组合。 (255, 0, 0)代表红色. (0, 255, 0)代表绿色, (255, 0, 255) 为紫色,以此类推可以创建丰富多彩的颜色。由于每个像素为8 x 3 bits (每个通道为8 bits)位深为24。

下面是此图的参数.
    •  位深为 24 bit
    • 3 channels 
    • 高为4个像素 
    • 宽为5个像素
    • 图像分辨率为4x5.

Red, Green, Blue planes of a color imageR, G, B planes of a color image
  • if (img.empty())
如果 imread()函数载入图像失败,'img' 将不会载入任何数据,因此 'img.empty()' 将返回true. 检测载入图像,成功还是失败退出程序是有必要的。否则在执行imshow()函数时程序执行将崩溃。

  • bool Mat::empty()
This function returns true, if Mat::data==NULL or Mat::total() == 0

  •  //system("pause");
如果是采用 Visual Studio最好不要把这句注释掉,除非按任意键否则程序将一直暂停。如果注释掉,程序将在执行完立即退出用户看不到任何错误信息。
  • void namedWindow(const string& winname, int flags = WINDOW_AUTOSIZE);        // 这个函数是创建一个窗口

参数-
  • winname - 窗口的名称,会显示在新建窗口的标题栏
  • flags - 定义窗口尺寸,有两种选择
    • WINDOW_AUTOSIZE - 用户无法调整窗口尺寸,图像以原始分辨率显示
    • CV_WINDOW_NORMAL - 用户可以自由调整窗口大小
  • void imshow(const string& winname, InputArray mat);
这个函数是显示存储在 'mat' 里面的图片在一个winname的窗口.如果窗口参数 为WINDOW_AUTOSIZE图像将以原始大小显示,否则可以调整。

Parameters -
  • winname - 窗口的名称,会显示在新建窗口的标题栏.
  • mat - 存储图片数据

  • int waitKey(int delay = 0)
waitKey()函数等待特定时间按下键,指定为延迟delay (毫秒ms). 如果 delay 为0或者负数,即无限制等待直到按下某个键。这个函数返回按下键的ASCII值使得程序继续运行。如果没有在定义时间内按下任何键,程序降返回-1后继续运行。
  • void destroyWindow(const string& winname)
这个函数是用来关闭打开的窗口释放相关内存空间。

总结

当运行这个程序的时候,图像 'MyPic.JPG'呗载入变量 Mat的数据类型的'img' 中, 命名为'MyWindow'的窗口被打开,'img'载入窗口。这个图像的窗口一直被展示直到某个键按下


Create a Blank Image & Display 创建一个空白图像&图像显示

这段程序和之前的非常类似,这个是创建一个空白图像,之前一个是载入已存在的图像。

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#include "opencv2/highgui/highgui.hpp"#include <iostream>using namespace cv;using namespace std;int main( int argc, const char** argv ){  Mat img(500, 1000, CV_8UC3, Scalar(0,0, 100)); //create an image ( 3 channels, 8 bit image depth, 500 high, 1000 wide, //(0, 0, 100) assigned for Blue, Green and Red plane respectively. )if (img.empty()) //check whether the image is loaded or not{cout << "Error : Image cannot be loaded..!!" << endl;          //system("pause"); //wait for a key pressreturn -1;}namedWindow("MyWindow", CV_WINDOW_AUTOSIZE); //create a window with the name "MyWindow"imshow("MyWindow", img); //display the image which is stored in the 'img' in the "MyWindow" windowwaitKey(0);  //wait infinite time for a keypress     destroyWindow("MyWindow"); //destroy the window with the name, "MyWindow"return 0;}///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



Create & Display ImageCreate & Display Image

新的OpenCV函数
  •  Mat::Mat(int rows, int cols, int type, const Scalar& s);
这是Mat类众多构造函数中的一个,用来初始化目标的。

参数 :
  • rows - 2维数组列高 ( 图像高度的像素数目)
  • cols 2维数组行宽 ( 图像宽度的像素数目)
  • type - 指定为位深,  这里给的参数是CV_8UC3 8 bit 无符号整数三通道,下面是可能的参数选择
    • CV_8UC1 - 8 bit 无符号整数单通道
    • CV_8UC3 - 8 bit 无符号整数三通道
    • CV_64FC1 - 64 bit 浮点数单通道
  • s -初始化由s给出的值的每个数组元素。在上面的应用程序中,我给Scalar(0,0,100)。因此,它与0,第2通道(绿色平面)与0和100。所以,我的最终图像是红色的第3路(红平面)初始化我的第一个通道(蓝色平面)。你可以试试这三种不同的组合,看到了输出图像。
本章小结
在本章里,创建了500X1000的一个3通道的图像。8 bit 无符号整数三通道(8x3 = 24 bits per each pixel)  ,每个像素赋scalar 值为 (0,0,100),意思是第1、2个通道全为0,第3个通道都为100,所以看到实验结果显示的为一张红色图像。

0 0