编译了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. android:imeOptions

    转自:http://www.cnblogs.com/qiengo/archive/2012/05/03/2480857.html 默认情况下软键盘右下角的按钮为“下一个”,点击会到下一个输入框,保持软 ...

  2. mpvue + Vant weapp + 微信云服务 打造小程序应用

    写在前面的话: 从事小程序开发已经大半年的时间了,但是一直都是再用原生写项目.一直想着用框架自己写一个小程序,但苦于一直没有时间.正好最近项目搁置,有了空闲时间,就研究了下mpvue + Vant w ...

  3. POJ1723 SOLDIERS 兄弟连

    SOLDIERS 有一个性质:在一个长为n的序列a中找一个数 \(a_k\) 使得 \(\sum\limits_{i=1}^n abs(a_i-a_k)\) 最小,则 \(a_k\) 是a的中位数. ...

  4. Exchange Server 2010邮件策略与遵从性

    本文档附带了一个附档,里面详细的描述了如何在Exchange Server 2010中配置如下内容: 1.邮件分类 2.免责申明 3.配置信息隔离墙 4.邮件审核 5.Exchange 2010与AD ...

  5. SSM整合搭建过程中的一个怪异问题

    好久没有搭建框架了,昨天开始试图搭建一个SSM框架,各种配置文件搭建成功,服务器也启动正确,但是在运行过程中,发现总是不能获取JDBC,不能够创建连接池工厂,报错如下:网页报500错误码 SEVERE ...

  6. 【转载】Asp .Net Web Api路由路径问题

    原文章地址:https://www.cnblogs.com/devtester/p/8897302.html MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一 ...

  7. 二十三、SAP中内表的修改

    一.通过MODIFY关键字来修改内表的内容,it相当于全部内容,wa相当于一条内容 二.效果如下

  8. CSU 1126 DFS前缀和

    在一棵树上找影响最小的某个点,某个点的影响是等于其他点到他的距离*其他点的权值 的和 我一开始也找不到什么好的方法,只能想到每个点暴力去判断,但是这样肯定会超时(10^5个点),又有点想用类似前缀和, ...

  9. 留学Essay写作中常见的两类要求词盘点

    写essay的时候,我们会常常因为各式各样的要求词而头疼:discuss,describing,evaluate,explain,等等,他们之间有何区别?如果你在思考这个问题,那么这篇文章就是为你写的 ...

  10. es6的...

    es6的...      (1):函数rest参数和扩展          sum1(...sum){//传多个参数             let total=0;             for( ...