halcon/c++接口基础 之 HALCON图像变量类
在halcon/c++中,hobject是一个基类,可以表示图像变量。另外还有三种类继承自hobject.
class himage 处理图像 class hregion 处理区域 class hxld 处理多边形regions
一个region是图像平面坐标点的集合。这样一个区域不需要被连通,而且可能还有好多洞。a region可以比实际的图像大。区域在halcon中可以用所谓的行程编码实现。类hregion代表halcon/c++中的一个区域。hregion的成员函数如下(列举几个重要的):
hregion(void)默认构造器。创造一个空的region,即region的面积是0.并不是所有的算子都可以将空region作为输入参数,例如一些shape property 操作。 hregion(const hregion ®)
拷贝构造函数 hregion &operator = (const hregion ®)
赋值运算符 void display(const hwindow &w) const
在一个窗口中输出region
区域的几何变换
hregion operator * (double scale) const放缩区域到任何一个尺度。放缩中心为(0,0) hregion operator + (const hdpoint2d &point) const
hregion &operator += (const hdpoint2d &point)
平移
区域的形态学处理:
hregion operator >> (double radius) consthregion &operator >>= (double radius)
用一个圆腐蚀,同erosion_circle hregion operator << (double radius) const
hregion &operator <<= (double radius)
用一个圆膨胀,同 dilation_circle. hregion &operator ++ (void)
用一个含有五个点的十字交叉去膨胀。 hregion &operator
-- (void)
用一个含有五个点的十字交叉去腐蚀。 hregion operator + (const hregion ®) const
hregion &operator += (const hregion ®)
与另一个区域的minkowsky 加和, 同 minkowski_add1. hregion operator - (const hregion ®) const
hregion &operator -= (const hregion ®)
与另一个区域的minkowsky 减法, 同 minkowski_sub1.
区域的属性:
double phi(void) const
一个等价的椭圆的角度,同 elliptic_axis. double ra(void) const
一个区域的等价的椭圆的长半轴,同 elliptic_axis. double rb(void) const
一个区域的等价的椭圆的短半轴,同elliptic_axis. long area(void) const
区域的面积,即所包含的像素数,见 area_center. double x(void) const
double y(void) const
区域的中心点坐标,见area_center. hrectangle1 smallestrectangle1(void) const
区域的最小包围盒,此包围盒平行于坐标轴,同 smallest_rectangle1. hbool in(const hdpoint2d &p) const
检验一个点是否在区域内部,同 test_region_point. hbool isempty(void) const;
检验区域是否为空,也就是区域面积是否为0
例1
#include "halconcpp.h" using namespace halcon; void main() { himage image("e:\\halcon\\images\\mreut.png"); // reading an aerial image hregion region = image >= 190; // calculating a threshold hwindow w; // display window w.setcolor("red"); // set color for regions region.display(w); // display the region hregion filled = region.fillup(); // fill holes in region filled.display(w); // display the region // opening: erosion followed by a dilation with a circle mask hregion open = (filled >> 4.5) << 4.5; w.setcolor("green"); // set color for regions open.display(w); // display the region hdpoint2d trans(-100, -150); // vector for translation hregion moved = open + trans; // translation hregion zoomed = moved * 2.0; // zooming the region }
first, an aerial image (mreut.png) is read from a file. all pixels with a gray value ≥ 190 are selected. this results in one region (region). this region is transformed by the next steps: all holes in the region are filled (fillup), small parts of the region are eliminated by two morphological operations, first an erosion, a kind of shrinking the region, followed by a dilation, a kind of enlarging the region. the last step is the zooming of the region. for that the region is first shifted by a translation vector ( ? 100, ? 150) to the upper left corner and then zoomed by the factor two. figure 6.2 shows the input image and the result of the opening operation.
region arrays
hregionarray是一个包含region的容器。代表成员函数如下:
long num(void)
数列的个数,最大序号是num() ? 1. hregion const &operator [] (long index) const
读取数组的第i个元素,序号是 0 … num() ? 1. hregion &operator [] (long index)
将一个region赋值给区域的第j个元素,the index index can be ≥ num(). hregionarray operator () (long min, long max) const
选取介于min与max之间的数据 hregionarray &append(const hregion ®)
将一个region附加到region array的后面
许多接受region的算子都接受region array作为输入参数。如形态学操作。
例2
#include "halconcpp.h" using namespace halcon; void main() { himage image("e:\\halcon\\images\\control_unit.png"); // reading an image from file // segmentation by regiongrowing hregionarray regs = image.regiongrowing(1, 1, 4, 100); hwindow w; // display window w.setcolored(12); // set colors for regions regs.display(w); // display the regions hregionarray rect; // new array for (long i = 0; i < regs.num(); i++) // for all regions in array { // test size and shape of each region if ((regs[i].area() > 1000) && (regs[i].compactness() < 1.5)) rect.append(regs[i]); // if test true, append region } image.display(w); // display the image rect.display(w); // display resulting regions }
原图
变换后图像
the first step is to read an image. in this case it shows a control unit in a manufacturing environment, see figure 6.4 on the left side. by applying a regiongrowing algz喎?/kf/ware/vc/" target="_blank" class="keylink">vcml0ag0gznjvbsb0agugsefmq09oigxpynjhcnkgdghligltywdliglzihnlz21lbnrlzcbpbnrvihjlz2lvbnmuievhy2ggcmvnaw9uigluc2lkzsb0agugcmvzdwx0aw5nihjlz2lvbibhcnjhesbyzwdziglzig5vdybzzwxly3rlzcbhy2nvcmrpbmcgdg8gaxrzihnpemugyw5kigl0cybjb21wywn0bmvzcy4grwfjacbyzwdpb24gb2ygysbzaxpligxhcmdlcib0agfuidewmdagcgl4zwxzigfuzcbvzibhignvbxbhy3ruzxnzihzhbhvlihntywxszxigdghhbiaxljugaxmgyxbwzw5kzwqgdg8gdghlihjlz2lvbibhcnjhesbyzwn0libbznrlcib0agugchjvy2vzc2luzybvzib0agugzm9yigxvb3agb25sesb0agugcmvnaw9ucybzag93aw5nig9uihrozsbyawdodcbzawrlig9migzpz3vyzsa2ljqgyxjligxlznquidwvy29kzt48l3a+dqo8admgawq9"images">images
在halcon中,矩阵叫做通道,一个图像可能由若干个通道组成。比如灰度图像由一个通道,而彩色图像由3个通道组成。通道的类型不仅仅是8位(btype),而且可以有其他类型(比如16 int2)以及实数类型。除了保存像素信息,每一个halcon图像也存储所谓的domain,就是上面介绍的那种region格式。region可以理解为感兴趣的区域,即roi。一般除了些许异常外,halcon算子都运行在region上处理。这一点与sepera相同。
image objects
类himage是所有继承的图像类的根类。通过使用himage,所有不同的像素类型都可以被以统一的格式处理(多态性)。类himage不是虚类,因此可以被实例化。如下列举了几个重要的成员函数:
himage(void)
默认构造函数,空的图像。 himage(const char* file)
从一个文件中读取图像,同read_image himage(int width,int height,const char* type)
构造一幅图像,指定了大小和类型。同gen_image_const himage(void *ptr, int width, int height, const char *type)
构造一幅图像,使用拷贝的方式,指定图像的大小和类型,同gen_image1. irtual const char *pixtype(void) const
像素类型,同 get_image_type. int width(void) const
图像宽,见get_image_size. int height(void) const
图像高,见 get_image_size. hpixval getpixval(int x, int y) const
获取(x,y)处的像素值,见 get_grayval. hpixval getpixval(long k) const
线性获得第k个像素值 virtual void setpixval(int x, int y, const hpixval &val)
设置第(x,y)个像素值,同 set_grayval. virtual void setpixval(long k, const hpixval &val)
设置第k个像素值 virtual void display(const hwindow &w) const
在一个窗口上显示图像
几何运算
- himage operator & (const hregion ®) const
裁剪图像的一部分区域,然后返回此部分的图像。同reduce_domain.
点评: 此函数设计的还是很好的,比较符合直觉。一幅图像与区域做&运算,就是获取共同的部分,也就是裁剪后的图像。himage operator + (const himage &add) const
图像相加,同 add_image. himage operator - (const himage &sub) const
图像相减,同 sub_image. himage operator * (const himage &mult) const
图像相乘,同 mult_image. himage operator - (void) const
图像取反, invert_image. himage operator + (double add) const
himage operator - (double sub) const
himage operator * (double mult) const
himage operator / (double p) const
图像加减乘除,同scale_image hregion operator >= (const himage &image) const
hregion operator <= (const himage &image) const
selecting all pixel with gray values brighter than or equal to (or darker than or equal to, respectively) those of the input image, see**dyn_threshold**
点评:动态阈值,局部阈值处理,一般和均指图像做比较。 hregion operator >= (double thresh) const
hregion operator <= (double thresh) const
hregion operator == (double thresh) const
hregion operator != (double thresh) const
阈值处理,同 threshold. 例3
#include "halconcpp.h"
using namespace halcon;
#include "hiostream.h"
#if !defined(use_iostream_h)
using namespace std;
#endif
void main()
{
himage image("e:\\halcon\\images\\mreut.png"); // aerial image
hwindow w; // output window
image.display(w); // display image
// returning the size of the image
cout << "width = " << image.width();
cout << "height = " << image.height() << endl;
// interactive drawing of a region by using the mouse
hregion mask = w.drawregion();
// reduce the domain of the image to the mask
himage reduced = image & mask;
w.clearwindow(); // clear the window
reduced.display(w); // display the reduced image
// applying the mean filter in the reduced image
himage mean = reduced.meanimage(61, 61);
mean.display(w);
hregion reg = reduced <= (mean -3);
reg.display(w);
}
本例首先从文件中读取一幅灰度图像,目的是提取暗的部分。截取部分区域处理只是为了节省时间。可以通过鼠标任意画出部分区域来选择我们处理的部分图像区域。这部分区域掩模用于作为输入去截取图像(运算符&).带有61x61大小的均指掩模被应用于最后截取的图像获得均值图像。暗的像素通过应用算子<= 选取。所有的像素不超过均值-3的都选取。 具体可以参考 dyn_threshold.pixel values
hpixval被用来访问类himage的像素值。灰度值可以独立于他们的类型而返回和设置。
如下介绍常见的成员函数:
//构造
hpixval(void)
default constructor.
hpixval(const hcomplex &val)
constructing a pixel value from a complex number.
hpixval(int val)
constructing a pixel value from an integer (int).
hpixval(long val)
constructing a pixel value from a long (long).
hpixval(hbyte val)
constructing a pixel value from a byte (byte).
hpixval(double val)
constructing a pixel value from a double (double).
hpixval(const hpixval &val)
copy constructor.
hpixval &operator = (const hpixval &grey)
assignment operator.
operator hbyte(void) const
converting a pixel value to byte (0 … 255). //强制转换
operator int(void) const
converting a pixel value to int.
operator long(void) const
converting a pixel value to long.
operator double(void) const
converting a pixel value to double.
operator hcomplex(void) const
converting a pixel value to complex.
例4
#include "halconcpp.h"
#include "hiostream.h"
#if !defined(use_iostream_h)
using namespace std;
#endif
using namespace halcon;
void main()
{
hbyteimage in("e:\\halcon\\images\\mreut.png"); // aerial image
hwindow w; // output window
in.display(w); // displaying the image
hbyteimage out = in; // copying the image
int width = out.width(); // width of the image
int height = out.height(); // height of the image
long end = width * height; // number of pixel of the image
// 1. run: linear accessing
for (long k = 0; k < end; k++) {
int pix = in.getpixval(k); // reading the pixel
out.setpixval(k, 255 - pix); // setting the pixel
}
// displaying the transformation
cout << "transformed !" << endl; out.display(w); w.click();
cout << "original !" << endl; in.display(w); w.click();
// 2. run: accessing the image via the coordinates (x,y)
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pix = in.getpixval(x, y); // reading the pixel
out.setpixval(x, y, 255 - pix); // setting the pixel
}
}
// displaying the transformation
cout << "transformed !" << endl; out.display(w); w.click();
cout << "original !" << endl; in.display(w); w.click();
}
类hpixval可以由上面的例子(图像取反)说明。 输入图像是一个灰度图像。首先一幅图像被复制,并且获得了图像大小。第一次运行,像素线性获得。第二次运行像素值通过(x,y)坐标获得。
点评: 本例的实质是观察int与hpixval的隐式转换。首先setpixval的第三个参数应该是hpixval,但是输入实际上是int,由于类hpixval提供了
hpixval(int val)的构造函数,使得隐式转换可以成功。后面getpixval获取像素,又由于类hpixval提供了
operator int(void) const的转换函数,使得
int pix = in.getpixval(k);是有效的。
image arrays
同之前定义region的数组,himage也定义了其数组,即himagearray.
成员函数如下:
himagearray(void)
default constructor: empty array, no element.
himagearray(const himage ®)
constructing an image array from a single image.
himagearray(const himagearray &arr)
copy constructor.
~himagearray(void)
destructor.
himagearray &operator = (const himagearray &arr)
assignment operator.
long num(void) const
returning the number of elements in the array.
himage const &operator [] (long index) const
reading the element i of the array. the index is in the range 0 … num() ? 1.
himage &operator [] (long index)
assigning an image to the element i of the array. the index index can be ≥ num().
himagearray operator () (long min, long max)
selecting a subset between the lower min and upper max index.
himagearray &append(const himage &image)
appending another image to the image array.
himagearray &append(const himagearray &images)
appending another image array to the image array.
byte image
对于每一个像素类型,存在着从himage继承的图像类,如对于像素类型byte(standard 8 bit),对应着hbyteimage;对于像素类型int2(signed 16 bit),对应着hint2image。但是使用最广泛的是hbyteimage,基本上覆盖了图像处理的大部分领域。hbyteimage相对于himage的优点是简化了像素值的访问机制。主要是因为hpixval不再使用。除了himage的成员函数外,hbyteimage还包含了以下扩展:
像素的设置和获得
hbyte &operator[] (long k)
线性设置第k个像素 hbyte operator[] (long k) const
线性读取第k个像素 hbyte &operator() (long k)
线性设置第k个像素 hbyte operator() (long k) const
线性读取第k个像素 hbyte &operator()(int x, int y)
通过坐标(x,y)设置像素 hbyte operator()(int x, int y) const
坐标(x,y)处的像素
位运算
hbyteimage operator & (int i)
与i与运算 hbyteimage operator << (int i)
每个像素做左移i位. hbyteimage operator >> (int i)
每个像素右移i位 hbyteimage operator ~ (void)
对每个像素去补 hbyteimage operator & (hbyteimage &ima)
两图像对应像素取 & hbyteimage operator | (hbyteimage &ima)
两图像对应像素取 | hbyteimage operator ^ (hbyteimage &ima)
两图像对应像素取 异或
例5
#include "halconcpp.h"
#include "hiostream.h"
#if !defined(use_iostream_h)
using namespace std;
#endif
using namespace halcon;
void main()
{
hbyteimage in("e:\\halcon\\images\\mreut.png"); // aerial image
hwindow w; // output window
in.display(w); // displaying the image
hbyteimage out = in; // copying the image
int width = out.width(); // width of the image
int height = out.height(); // height of the image
long end = width * height; // number of pixel of the image
// 1. run: linear accessing
for (long k = 0; k < end; k++) {
out[k] = 255 - in[k]; // setting the pixel
}
// displaying the transformation
cout << "transformed !" << endl; out.display(w); w.click();
cout << "original !" << endl; in.display(w); w.click();
// 2. run: accessing the image via the coordinates (x,y)
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
out(x, y) = 255 - in(x, y); // setting the pixel
}
}
// displaying the transformation
cout << "transformed !" << endl; out.display(w); w.click();
cout << "original !" << endl; in.display(w); w.click();
}
本例是例4的改造版,看起来更简洁,更像c语言的风格。访问像素不再需要get/set格式。
xld objects
xld是extented line description的简称。这种数据结构可以描述areas(即任意大小的区域或者多边形)or 任何封闭的或者打开的轮廓。与regions代表像素精度相反,xld代表的是亚像素精度。其中有两种基本的xld结构: 轮廓(contours)和 多边形(polygons).
与图像相似,halcon/c++也提供了基类hxld和一些继承自hxld的特殊类,比如hxldcont用于轮廓,hxldpoly用于多边形。另外也存在一个容器类,即hxldarray.
low—level iconic objects
当以面向过程的方式调用算子时,hobject可以被用来代表所有的图像参数,如 an image,a region,an image array.事实上,hobject是halcon访问内部数据的基类。并且,hobejct也可作为hobject和hobject继承类,如himage的基类。
hobject有如下的成员函数:
hobject(void)
default constructor.
hobject(const hobject &obj)
copy constructor.
virtual ~hobject(void)
destructor.
hobject &operator = (const hobject &obj)
assignment operator.
void reset(void)
freeing the memory and resetting the corresponding database key.
正如前面所讲,hobject的对象也可以包含一个图像数据的数组。但是不幸的是,hobject没有特殊的函数区增加和选择数组成员,取而代之的是,你必须使用“the tuple mode”.一节所描述的算子
gen_empty_obj, concat_obj, select_obj, and count_obj 代替。