zoukankan      html  css  js  c++  java
  • OpenCV2+入门系列(二):图像的打开、创建与显示(命令行)

    前置知识:数字图像的简略知识

    这里只是最基础的知识,上课如果稍微听了课的同学可以直接略过不不看。

    彩色图像:

    对于一副数字图像,对于一副RGB色彩空间的彩色数字图像,它一共有宽X高个像素格子,每个格子的色彩由蓝色、绿色、红色三个原色合成,很简单吧,三原色的合成大家小学就学过喽。计算机中B、G、R三个值可以从0至255选择,不同的值的组合就可以合成出不同的色彩,一般来说总共可以组成255*255*255种色彩。

    灰度图像:

    而若是图像中所有像素都是由黑到白(0到255)的亮度表示,那么这幅图像将是一副只有灰色的图像(想象一下黑白照片)。

    二值图像:

    在灰度图像中,把所有亮度大于某个值(二值化阈值)的像素点的亮度设置为255,其余的设置为0,那么就得到了二值图像,它将是只有黑色与白色两种颜色的图像,类似于黑白木刻画。

    1.图像的打开

    假设大家在C++编程上已经有所建树,而且也大致了解了类、对象、命名空间,那么为了使用OpenCV的相关函数,首先要添加相应的头文件。我们将core.hpp,highgui.hpp添加,并且引用cv这个命名空间。

    1.1 打开现有图片

    OpenCV 2+版本中图像的存储类型为Mat型,载入图像的函数为imread,显示图像的函数为imshow,很简单吧,只需要几个函数你就可以写出一个图片浏览器(笑~)。

    因为太简单了,所以直接放代码:

    #include "stdafx.h"
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    using namespace cv;
    int main() {
        Mat image = cv::imread("img.jpg");//读取img.jpg到image中,此处可以写相对路径也可以写绝对路径
        namedWindow("图片1");//定义一个名为“图片1”的窗口
        imshow("图片1", image);//在窗口“图片1”中显示image
        waitKey();//等待按键
        return 1;
    }

     每句话都有注释,简单易懂不是吗。由于这里提前引用了cv这个namespace,所以不必每句话前加一个"cv:",否则你将看到这样的代码:

    #include "stdafx.h"
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    int main() {
        cv::Mat image = cv::imread("img.jpg");//读取img.jpg到image中,此处可以写相对路径也可以写绝对路径
        cv::namedWindow("图片1");//定义一个名为“图片1”的窗口
        cv::imshow("图片1", image);//在窗口“图片1”中显示image
        cv::waitKey();//等待按键
        return 1;
    }

    总之最后的效果应该是这样的:

    简单说明一下:

    1 Mat类型是OpenCV2中用于保存图像或者矩阵信息的数据结构。初始化时可以用上面的方法,直接imread一张图片,也可以指定初始尺寸和初始色彩,这个我们之后再说。

    2 通过imread函数,我们可以从指定的路径加载一张图片到内存中(存为Mat型变量)。它的函数原型为:

    可以知道它有一个默认参数flags = 1,它表示程序打开的图像默认为三通道的(即BGR三通道),为彩色图像,如果在调用函数时设置flags = 0,那么就会把图像加载成灰度图像(单通道)。当它设置为-1,2,4时都还有另外的意义,不过更详细的函数说明你就要出门左转去看OpenCV的官方手册了,毕竟我这文章也不是文档翻译对吧。

    当然有时候你无法确定自己指定的图片是否能够被顺利打开(图片不存在、图片损坏等),因此在使用打开的图像时,最好判断一下图像是否正确读取了,就像这样。

        Mat image = imread("img.jpg",CV_LOAD_IMAGE_COLOR);//读取img.jpg到image中,此处可以写相对路径也可以写绝对路径
        if(!image.data)
        {
            //do something图片没有被读取成功
        }

     3 在使用imshow函数显示图像之前,记得一定要先用namedWindow定义一个窗口,窗口参数可以设置大小、位置、缩放等,具体也请去看官方文档。

    1.2在内存中创建图像

    OK,当然除了从文件读取图像外,我们还可以直接在计算机内存中创建一副图像。我们是这样做的,如图,在定义一个Mat变量时有24种重载可以用来指定变量的初始值。

    //你可以这样写:
    Mat image2(319,480,CV_8UC3,Scalar(255,0,0));
    //这样写:
    Mat image3(image.size(),CV_8UC3,Scalar(0,255,0));
    //或者这样写:
    Mat image4(image);

     第一种写法表示创建一副宽480,高319的8位3通道彩色图像,颜色为255的蓝色。代码中CV_8UC3是一个宏定义,表示的就是8位3通道彩色图像,类似的宏定义还有CV_8U,它表示的是八位灰度图像。Scalar(255,0,0)表示的是创建图像的颜色,三个数字分别表示BGR通道。

    第二种写法表示的是创建一个image一样大的绿色图像。

    第三章写法则表示直接复制了一个image图像到image4的内存空间。

     

    二、Mat对象的存储格式(简略)

    本节很重要,只有了解了Mat变量才能很好的操作图像!

    本节很重要,只有了解了Mat变量才能很好的操作图像!

    因为很重要,所以说两遍,可是如果要详细说Mat的话,估计一整篇文章都不够,所以这里只能简略的讲讲。

    Mat类是用于保存图像的数据结构,它的默认尺寸为0,载入图像数据的方法在上文中已经说了,忘记的同学赶快回去复习。Mat对象在离开作用域以后会其分配的内存会自动被释放,终于不用像以前那样cvRelease图像了。以下是Mat类的简略结构:

    Mat
    {
    public/ / … …很多的方法...
    ...
    /*!包括几位字段:
    -神奇的签名
    -连续性标志
    -深度(Note:应该是位深)
    -通道数
    */
    int flags;(Note :目前还不知道flags做什么用的)
    //!数组的维数,> = 2
    int dims ;
    //!行和列的数量或 (-1,-1) 此时数组已超过 2 维
    int rows,cols;
    //!指向数据的指针
    uchar *data ;
    //!指针的引用计数器 ;
    / / 阵列指向用户分配的数据时,当指针为 NULL
    int * refcount ;
    / / 其他成员
    ...
    };

    Mat.step定义了数据布局,它代表了图像一行的像素占据的数据长度。而Mat. Data则指向了数组数据的开头,还有一个Mat.elemSize()将返回数组元素的长度。因此第N行第M列的数据可以这样来取,公式并不难理解。

    Data = Mat.data + (N - 1)×Mat.step + (M - 1)×Mat.elemSize();

    Mat. channels()则表示图像的通道数目,若为灰度图像,那么数据的存放没什么好说的,第一行一个个像素一次排下去,然后是第二行、第三行。如果是三通道,则先存第一个像素的B通道值、然后是G通道值、最后是R通道值。接着再存第二个像素,第三个像素……

    恩,好像就说这么多已经足够了,其余的用法等进阶学习以后边用边学就行,有什么遗漏的话以后再重新编辑博文吧。得赶快结束了,我发现这篇文章已经有点太长了……

    作者:VShawn

    出处:http://www.cnblogs.com/singlex/

    本文版权归作者所有,欢迎转载,但未经博客作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    Mysql登录错误:ERROR 1045 (28000): Plugin caching_sha2_password could not be loaded
    Docker配置LNMP环境
    Docker安装mysqli扩展和gd扩展
    Docker常用命令
    Ubuntu常用命令
    单例模式的优缺点和使用场景
    ABP 多租户数据共享
    ABP Core 后台Angular+Ng-Zorro 图片上传
    ERROR Error: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions.
    AbpCore 执行迁移文件生成数据库报错 Could not find root folder of the web project!
  • 原文地址:https://www.cnblogs.com/singlex/p/4060771.html
Copyright © 2011-2022 走看看