编译了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. 玩个JAVA爬虫,没想玩大

    想玩个爬虫,爬些数据玩玩,不成想把自己玩“进去”了 想爬这个新浪的股票 大额交易页面 本以为用 HttpClient 直接爬链接,结果发现这个页面中,翻页数据压根就是动态赋值的,根本没有,那我根本无法 ...

  2. 0101-ioc

    背景 ioc是spring的基础,即控制反转.springboot基于注解使用ioc. ioc spring称所有被管理的对象为bean, spring ioc主要通过描述的方式完成3类bean的管理 ...

  3. C++用sqlite3_open连接打开指定数据库的小问题

    一开始我也纳闷,我以为是我数据库没弄好,但是当我仔细检查,才发现 原来我少了分号 写少了分号,可能会导致  database    和  table    找不到... 所以用的时候需要注意... 代 ...

  4. 《YouTube 网站的架构演进》阅读笔记

    概述 YouTube 在国内是个404网站,需要翻墙得见,这是有用的废话,先铺垫一下. 从全球网站来看,它仅次于母公司 Google,全球排名位列第2.每天超过5亿以上视频播放量,平均每个用户点击10 ...

  5. springboot创建bean

    springboot创建bean的方式有两种: 1.直接类上加注解@Component@Controller@Service ... 2.使用@Bean注解配合@Configuration注解 区别是 ...

  6. WMware workstation 镜像文件

    https://mirrors.aliyun.com/centos/7.4.1708/isos/x86_64/

  7. @Resource 和@Autowired区别

    @Autowired 该注解是由spring提供的 按照类型注入 public class UserService { @Autowired private UserDao userDao; } 这样 ...

  8. http 请求code状态码

    状态码 含义 100 客户端应当继续发送请求.这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝.客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应.服务器必须在 ...

  9. Oracle的操作经验

    采用Oracle进行sql语句 建表并设置主键,主键自增,某一字段唯一性约束等 <---如果表存在则删除---> declare num number; begin select coun ...

  10. 127-PHP类通过魔术变量判断类中是否存在指定的方法

    <?php class ren{ //定义人类 //定义成员属性 private $name='Tom'; private $age=15; //定义成员方法 public function g ...