Dlib笔记一:基本数据结构和基本操作

21 篇文章 3 订阅

编译了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有关的应该大概就这些基本操作。

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

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

居善地,

心善渊,

与善仁,

言善信,

政善治,

事善能,

动善时。

夫唯不争,故无尤。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值