编译了Dlib之后就开始想着怎么用起来,先从基本的数据类型说起吧,因为是图像,所以难免会跟OpenCV的数据类型比较。在Dlib中,图像是用二维阵列(array2d)或者矩阵(matrix)来表示的,matrix和array2d的很多操作其实是一样的,所以这一篇还是以array2d的操作为主来讲,matrix的操作基本上也是这样。

array2d是有行数、列数、像素类型等参数的,定义好一个array2d之后,可以通过set_size()来设置尺寸,通过nc()来获取阵列的列数,通过nr()来获取阵列的函数;如果要获取数据的地址,可以通过调用image_data()函数来获取,会返回一个void*的指针,要根据像素的数据类型来转为相应的指针。array2d是一个模板类,在实例化一个array2d对象的时候是要声明图像的像素数据类型的。array2d有几种数据类型,rgb三通道(rgb_pixel)、bgr三通道(bgr_pixel)、rgba四通道(rgb_alpha_pixel)、HSI空间数据类型(hsi_pixel)、lab空间数据类型(lab_pixel)、灰度图(unsigned char)。所以,在定义一个图像变量的时候,要先声明好变量的数据类型的:

array2d<rgb_pixel> img0;     //rgb彩色图
array2d<bgr_pixel> img0;     //bgr彩色图
array2d<unsigned char> img0; //灰度图

接下来,就是从本地加载图像进来,这里,Dlib支持常见的bmp、jpg、jpeg、png、gif等几种格式,这里要说的是几种格式是要根据前面编译的时候是否加了依赖的库的,前面我编译的时候只加了jpg、png,所以,这里的gif是不支持的。加载图像的函数接口为:

template <typename image_type>
void load_image (
    image_type& image,
    const std::string& file_name
)

这是一个模板函数,所以我这里就只截取函数头部分,就是传入一个二维阵列的引用和图像的本地地址。图像加载接口的头文件可以包含<dlib/image_io.h>,因为这个头文件里包含了几种格式加载的头文件。加载了图像之后就要显示出来,Dlib也有自己的GUI来显示图像,头文件为"dlib/gui_widgets.h",要显示图像就要先定义一个GUI窗口对象,然后设置要显示的图像:

image_window win0;    
win0.set_image(img0);

在定义好窗口对象的时候就已经显示窗口了,所以直接设置要显示的图像即可,当图像为空的时候,窗口设置图像并不会导致发生错误,因此倒是显示这里倒是可以省略判断。与OpenCV类似的是,设置好图像之后如果不让窗口等着的话也是会一闪而过的,所以就要调用等待的函数让窗口显示直到关闭,所以最好就是把等待这一步放到最后:

win0.wait_until_closed();

这个函数就是会将程序停在这里,直到这个窗口关闭,这个相比OpenCV来说就不太好一点。

Dlib也支持将一幅图像赋值给另一幅图像,这里使用assign_image操作,其接口为:

template <
    typename dest_image_type,
    typename src_image_type
    >
void assign_image (
    dest_image_type& dest,
    const src_image_type& src
)

这里要求目标图像和原图像的图像格式是要一样的。如果不一样,也不会报错,但是得到的目标图像好像是空的,但是会按照目标图像的格式来转存。assign_image操作应该属于深拷贝操作,更改目标图像是不会导致原图像跟着改变的。这里可以通过以下代码测试

string img_path = "";
if (argc != 2)
{
img_path = "D:/lena.jpg";
}
else
{
img_path = argv[1];
}
image_window win0;
win0.set_title("img0");
array2d<rgb_pixel> img0;
load_image(img0, img_path);
win0.set_image(img0);
array2d<unsigned char> img1;
image_window win1;
image_window win2;
assign_image(img1, img0);
if (img1.size() > 0)
{
win1.set_title("img1");
win1.set_image(img1);
//win1.wait_until_closed();
}
array2d<rgb_pixel> img2;
win2.set_image(img2);
assign_image(img2, img1);
if (img2.size() > 0)
{
win2.set_title("img2");
win2.set_image(img2);
//win2.wait_until_closed();
}
assign_all_pixels(img2, rgb_pixel(0, 255, 0));
win1.set_image(img1);
win2.set_image(img2);
win0.wait_until_closed();

这里的assign_all_pixels函数是对图像的所有像素赋值为相同值,上述代码的结果如下:

上面提到的assign_all_pixels是对整幅图像赋值,其接口为:

template <
    typename dest_image_type,
    typename src_pixel_type
    >
void assign_all_pixels (
    dest_image_type& dest_img_,
    const src_pixel_type& src_pixel
    )

Dlib还支持对图像的边缘赋值,assign_border_pixels,其接口如下:

template <typename image_type>
void assign_border_pixels (
    image_view<image_type>& img,
    long x_border_size,
    long y_border_size,
    const typename image_traits<image_type>::pixel_type& p
)

或者赋值为0的zero_border_pixels接口。当然,还有对像素赋值的接口assign_pixel,其接口如下:

template <
    typename P1,
    typename P2 
    >
inline void assign_pixel (
    P1& dest,
    const P2& src
);

这里的话是把像素点src的强度赋值给dest,还有获取某个像素的强度和赋值某个像素新的强度的接口:

template <
    typename P
    >
inline typename pixel_traits<P>::basic_pixel_type get_pixel_intensity (
    const P& src
    );
    
template <
    typename P,
    typename T
    >
inline void assign_pixel_intensity (
    P& dest,
    const T& new_intensity
);

好了,基本上array2d有关的应该大概就这些基本操作。

上善若水,水善利万物而不争。

处眾人之所恶,故几於道。

居善地,

心善渊,

与善仁,

言善信,

政善治,

事善能,

动善时。

夫唯不争,故无尤。

Dlib笔记一:基本数据结构和基本操作的更多相关文章

  1. Elasticsearch笔记二之Curl工具基本操作

    Elasticsearch笔记二之Curl工具基本操作 简介: Curl工具是一种可以在命令行访问url的工具,支持get和post请求方式.-X指定http请求的方法,-d指定要传输的数据. 创建索 ...

  2. Redis学习笔记一:数据结构与对象

    1. String(SDS) Redis使用自定义的一种字符串结构SDS来作为字符串的表示. 127.0.0.1:6379> set name liushijie OK 在如上操作中,name( ...

  3. MYSQL基础笔记(二)-SQL基本操作

    SQL基本操作 基本操作:CRUD,增删改查 将SQL的基本操作根据操作对象进行分类: 1.库操作 2.表操作 3.数据操作 库操作: 对数据库的增删改查 新增数据库: 基本语法: Create da ...

  4. Java学习笔记——浅谈数据结构与Java集合框架(第一篇、List)

    横看成岭侧成峰,远近高低各不同.不识庐山真面目,只缘身在此山中. --苏轼 这一块儿学的是云里雾里,咱们先从简单的入手.逐渐的拨开迷雾见太阳.本次先做List集合的三个实现类的学习笔记 List特点: ...

  5. python 学习笔记一 (数据结构和算法)

    2018年刚刚过完年,从今天起,做一个认真的技术人.开始进入记笔记阶段. python内置了很多数据结构,list , set,dictionary 1.将序列分解为单独的变量 1.1 通过赋值的方式 ...

  6. Redis(1.2)Redis的数据结构与基本操作

    Redis的数据结构,其本身大方向是键值对 [0]大概特点 相关产品:Redis.Riak.SimpleDB.Chordless.Scalaris.Memcached 形式:Key 指向 Value ...

  7. [redis读书笔记] 第一部分 数据结构与对象 简单动态字符串

    本读书笔记主要来自于<<redis设计与实现>> -- 黄键宏(huangz) redis主要设计了字符串,链表,字典,跳跃表,整数集合,压缩列表来做为基本的数据结构,实现键值 ...

  8. 读书笔记:《数据结构与算法分析Java语言描述》

    目录 第 3 章 表.栈和队列 3.2 表 ADT 3.2.1 表的简单数组实现 3.2.2 简单链表 3.3 Java Collections API 中的表 3.3.1 Collection 接口 ...

  9. javascript学习笔记10----字符串的基本操作

    1.字符串的基本操作如下: 定义字符串: var str = "Hello World!" 字符串的基本操作如下: str.length-----返回字符串长度,这里返回12 st ...

随机推荐

  1. 0108 spring的申明式事务

    背景 互联网的金融和电商行业,最关注数据库事务. 业务核心 说明 金融行业-金融产品金额 不允许发生错误 电商行业-商品交易金额,商品库存 不允许发生错误 面临的难点: 高并发下保证: 数据一致性,高 ...

  2. 剑指offer自学系列(一)

    题目描述:输入n个整数,找出其中最小的k个数,例如,输入{4,5,1,6,2,7,3,8}这8个数字,最小的4个数字是1,2,3,4 题目分析:首先我能想到的是先对数组排序,从小到大,然后直接输出想要 ...

  3. P1055 集体照

    P1055 集体照 转跳点:

  4. Live555研究之一 源代码编译

    Live555 是一个为流媒体提供解决方案的跨平台的C++开源项目,它实现了对标准流媒体传输协议如RTP/RTCP.RTSP.SIP等的支持.Live555实现了对多种音视频编码格式的音视频数据的流化 ...

  5. duilib之重写BUTTON按钮

    在使用BUTTON过程中,有时候发现一些属性不够用,或要从新绘制BUTTON按钮,那该如何操作?其实很简单,只需要继承CButtonUI类就行. 创建类CMyButtonUI,继承CButtonUI, ...

  6. 项目中常用的JS操作技巧

    1.<a>标签-超链接中confirm方法使用介绍 <a href="a.html" onclick="if(confirm('确定删除?')==fal ...

  7. Redis 详解 (五) redis的五大数据类型实现原理

    目录 1.对象的类型与编码 ①.type属性 ②.encoding 属性和 *prt 指针 2.字符串对象 3.列表对象 4.哈希对象 5.集合对象 6.有序集合对象 7.五大数据类型的应用场景 8. ...

  8. s5pc100开发板Nand flash移植

    相关软件下载地址:http://pan.baidu.com/s/16yo8Y fsc100开发板 交叉编译工具:arm-cortex_a8-linux-gnueabi-gcc Ÿ   添加针对我们平台 ...

  9. Pyinstaller的安装及简单使用

    (1)安装: 用传统的pip install pyinstaller出错,在https://pypi.org/project/PyInstaller/#files上下载PyInstaller-3.4. ...

  10. Java中定义常量(Constant) 的几种方法

    为了方便大家交流Spark大数据,浪尖建了微信群,目前人数过多,只能通过浪尖或者在群里的朋友拉入群.纯技术交流,偶有吹水,但是打广告,不提醒,直接踢出.有兴趣加浪尖微信. 常量使用目的 1,为什么要将 ...