CImg库快速学习笔记
中山大学,曾坤老师的《计算机视觉》需要。
本文部分翻译自CImg_latest安装包中附带的英文文档的8 Class Documentation部分,以及互联网中的参考资料。如有错漏,烦请提醒更正。
希望你看到这篇文章的时候中大计算机视觉课仍然在使用这个库。
还没写完,有空再补
CImg库只包含一个CImg.h文件,其中所有的类和函数都被定义在了cimg_library
命名空间中,所以一般来说可以直接将这个命名空间作为缺省命名空间使用:using namespace cimg_library
CImg<T>
下面的所有函数,如果没有特别指明,都为CImg<T>的成员函数(或属性)
图读写
CImg本身是一个泛型的类,一般而言接受一个unsigned char
的参数,可以使用CImg<unsigned char> xxx(height,width,?,?)
来创建空白图像,并进行填充,也可以使用字符串参数直接读写文件。
使用CImg.display("Windows name")
可以预览图像,便于调试
构造函数与赋值
- 无参数,构造一个空的图
- 四个参数,代表x,y,z,channel
- 五个参数,(x,y,z,channel)和默认填充值
- 4+n个参数,(x,y,z,channel)和两个以上的i参数作为数据
- assign()函数,默认为库内调用(in-place version),等同于同参数的构造函数。
- move_to(CImg ),将图像的所有内容传给参数中的这个CImg对象,并用一个空的实例来代替原来的对象。
- swap(CImg ),字面意思
- empt(),返回一个空图的引用
- clear(),等价与assign()的无参数版本
- load(filename),从文件中读取图片
调试数据与结果
- print(),输出
- display(),打印图像
- save(),保存
图像属性与辅助计算
- CImg<T>.width()/height()/depth()/spectrum() 返回宽度/高度/深度/通道数
- longT offset(const int x,y=0,z=0,c=0) 代表x,y,z,channel,计算位移offset
- pixel_type() 返回一个字符串作为CImg的数据类型
bool is_overlapped(const CImg<t> & img) const
检测图像重叠
全局辅助计算
- CImg<T>& sqr(),计算每个像素值的平方,并替换原来的值。
- CImg<T>& sqr(),计算每个像素值的平方根,并替换原来的值。
- CImg<T>& exp(),将每个像素值作为e的指数进行计算
- log() 自然对数,同,此外还有相似的log2、log10,数学上还有abs()、sign()、cos()、sin()、sinc(),等等。
- min(T value)、max(T value),将
I
x
,
y
,
z
,
c
I_{x,y,z,c}
Ix,y,z,c用
m
i
n
/
m
a
x
(
I
x
,
y
,
z
,
c
,
v
a
l
)
min/max(I_{x,y,z,c},val)
min/max(Ix,y,z,c,val)替代,value可以为另外一个图,表示原图会用相同坐标下更小/更大的值来替代
T kth_smallest(const ulongT k) const
,返回第k小的pixeldouble variance(const unsigned int variance_method = 1) const
方差,具体计算方法见文档。method = 0的时候前面除数为N,method = 1时除数为N-1,method=2时使用least median of squares,3为least trimmed of squares(不懂,等会查)
矩阵操作
CImg<T>& transpose()
转置,此外还有invert()等,以及cross()、solve()、eigen()
图像访问
迭代器与指针
- CImg<>.begin()/end(),同正常C++容器
- CImg<>.front(),返回对第一个像素的引用
- CImg<>.back(),返回对最后一个像素的引用
- CImg<>.data(),无参数版本返回第一个元素的指针
随机访问
- T& at(const int offset, const T &out_value)与T& at(const int offset),其中out_value为offset非法时的返回值
- at+(X/Y/Z/XY/XZ/YZ/XYZ/XYZC)等一般接受三个-五个参数,前面一组为坐标,最后一个为超界返回值
- T* data(x,y,z,c),返回指定位置的像素的指针
- 向量访问
CImg<T>& set_vector_at(const CImg<t>& vec,x,y,z)
与get_vector_at(x,y,z)
,此外含有matrix和tensor
范围访问
CImg<T> get_channel(const int c0) const
,返回指定image channel的值,此外还有get_channels()- rows()、cols()接受两个参数,返回范围;row()/col(),接受一个值,返回某列/行
CImg<T>& crop(x0,y0,z0,c0,x1,y1,z1,c1,boundary_conditions)
,返回(x0,y0,z0,c0)与(x1,y1,z1,c1)之间的值
存在检测
- contains():
bool contains(const T& pixel, t& x, t& y, t& z, t &c)
,检查图像边界内是否含有指定像素并且返回它的x,y,z,c值。
官方例程:将offset转为(x,y,z,c)
const CImg<float> img(100,100,1,3);
const unsigned long offset = 1249;
unsigned int x,y,z,c;
if (img.contains(img[offset],x,y,z,c))
{
std::printf("Offset %u refers to pixel located at (%u,%u,%u,%u).\n",offset,x,y,z,c);
}
此外contains()含有多个重载版本,区别在于t&参数的数量个数
图像修改
画图
- draw_point
- draw_line
- draw_triangle()
- draw_spline()
- draw_arrow()
- draw_rectangle()
- draw_polygon()
- draw_ellipse()
- draw_circle()
- draw_image()
- draw_text()
- draw_quiver()
- draw_axis()
图像循环
来源Document 6.7 Using Image Loops
全局循环
- cimg_for(img,ptr,T):在img的缓存区中循环,使用指针T* ptr,从缓存区的开始到缓存去的结束。(*ptr即为缓存区的每个元素的值)
- cimg_rof(img,ptr,T),与前者相同,但是从缓存区的结尾开始循环
- cimg_foroff(img,off),使用offset循环,off从0到img.size()-1
轴循环
- cimg_forX(img,x),等价于
for(int x=0;x<img.width();x++)
- 此外还有cimg_forY(img,y),以及z,c等
- 此外还有cimg_forXY(y为外层,x为内层),还有三个参数和四个参数的版本
内部区域和边界循环
- cimg_for_insideX(img,x,n),在x轴循环,不访问距离边界n个像素点的像素。
此外还有XY和XYZ版本 - cimg_for_border(img,x,n),x轴循环,只能访问距离边界n个像素点的像素。此外还有XY和XYZ版本。
领域循环
在图像循环中,取得周围像素的值往往十分重要
- cimg_for2x2(img,x,y,z,c,I,T),在(x,y)上循环使用中心2x2的邻域。此外还有3x3到5x5的版本。
在这里,x,y是内部定义的变量,不用在外部事先定义。img是一个非空的CImg<T>图像,z和c是常数,定义应该使用哪一个image slice 和vector channel。I是一个2x2(3x3或4x4或5x5)的邻域,类型为T。
邻域的定义:邻域被定义为是一个拥有[]
操作符的类。包括C数组和CImg<T>对象。例如3x3的邻域可以是一个float[9]
或是CImg<float>(3,3)
命令行参数检索
提供了三个宏:cimg_usage()、cimg_help()和cimg_option()。使用这些宏使从命令行检索选项值变得容易