3.1 圖像變量
在HALCON/C++中,HObject是一個基類,可以表示圖像變量。另外還有三種類繼承自HObject.
- Class HImage 處理圖像
- Class HRegion 處理區(qū)域
- Class HXLD 處理多邊形
Regions
一個region是圖像平面坐標點的集合。這樣一個區(qū)域不需要被連通,而且可能還有好多洞。a region可以比實際的圖像大。區(qū)域在HALCON中可以用所謂的行程編碼實現(xiàn)。類HRegion代表HALCON/C++中的一個區(qū)域。HRegion的成員函數(shù)如下(列舉幾個重要的):
- HRegion(void)
默認構(gòu)造器。創(chuàng)造一個空的region,即region的面積是0.并不是所有的算子都可以將空region作為輸入?yún)?shù),例如一些shape property 操作。 - HRegion(const HRegion ®)
拷貝構(gòu)造函數(shù) - HRegion &operator = (const HRegion ®)
賦值運算符 - void Display(const HWindow &w) const
在一個窗口中輸出region
區(qū)域的幾何變換
- HRegion operator * (double scale) const
放縮區(qū)域到任何一個尺度。放縮中心為(0,0) - HRegion operator + (const HDPoint2D &point) const
HRegion &operator += (const HDPoint2D &point)
平移
區(qū)域的形態(tài)學處理:
- HRegion operator >> (double radius) const
HRegion &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 ®)
與另一個區(qū)域的Minkowsky 加和, 同 minkowski_add1. - HRegion operator - (const HRegion ®) const
HRegion &operator -= (const HRegion ®)
與另一個區(qū)域的Minkowsky 減法, 同 minkowski_sub1.
區(qū)域的屬性:
- double Phi(void) const
一個等價的橢圓的角度,同 elliptic_axis. - double Ra(void) const
一個區(qū)域的等價的橢圓的長半軸,同 elliptic_axis. - double Rb(void) const
一個區(qū)域的等價的橢圓的短半軸,同elliptic_axis. - long Area(void) const
區(qū)域的面積,即所包含的像素數(shù),見 area_center. - double X(void) const
double Y(void) const
區(qū)域的中心點坐標,見area_center. - HRectangle1 SmallestRectangle1(void) const
區(qū)域的最小包圍盒,此包圍盒平行于坐標軸,同 smallest_rectangle1. - HBool In(const HDPoint2D &p) const
檢驗一個點是否在區(qū)域內(nèi)部,同 test_region_point. - HBool IsEmpty(void) const;
檢驗區(qū)域是否為空,也就是區(qū)域面積是否為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的容器。代表成員函數(shù)如下:
- long Num(void)
數(shù)列的個數(shù),最大序號是Num() ? 1. - HRegion const &operator [] (long index) const
讀取數(shù)組的第i個元素,序號是 0 … Num() ? 1. - HRegion &operator [] (long index)
將一個region賦值給區(qū)域的第j個元素,The index index can be ≥ Num(). - HRegionArray operator () (long min, long max) const
選取介于min與max之間的數(shù)據(jù) - HRegionArray &Append(const HRegion ®)
將一個region附加到region array的后面
許多接受region的算子都接受region array作為輸入?yún)?shù)。如形態(tài)學操作。
例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
}
![][1]
原圖
![][2]
變換后圖像
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 algorithm from the HALCON library the image is segmented into regions. Each region inside the resulting region array regs is now selected according to its size and its compactness. Each region of a size larger than 1000 pixels and of a compactness value smaller than 1.5 is appended to the region array rect. After the processing of the for loop only the regions showing on the right side of figure 6.4 are left.
Images
在Halcon中,矩陣叫做通道,一個圖像可能由若干個通道組成。比如灰度圖像由一個通道,而彩色圖像由3個通道組成。通道的類型不僅僅是8位(btype),而且可以有其他類型(比如16 int2)以及實數(shù)類型。除了保存像素信息,每一個HALCON圖像也存儲所謂的domain,就是上面介紹的那種Region格式。region可以理解為感興趣的區(qū)域,即ROI。一般除了些許異常外,halcon算子都運行在region上處理。這一點與sepera相同。
Image Objects
類HImage是所有繼承的圖像類的根類。通過使用HImage,所有不同的像素類型都可以被以統(tǒng)一的格式處理(多態(tài)性)。類HImage不是虛類,因此可以被實例化。如下列舉了幾個重要的成員函數(shù):
- HImage(void)
默認構(gòu)造函數(shù),空的圖像。 - HImage(const char* file)
從一個文件中讀取圖像,同read_image - HImage(int width,int height,const char* type)
構(gòu)造一幅圖像,指定了大小和類型。同gen_image_const - HImage(void *ptr, int width, int height, const char *type)
構(gòu)造一幅圖像,使用拷貝的方式,指定圖像的大小和類型,同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)
設(shè)置第(x,y)個像素值,同 set_grayval. - virtual void SetPixVal(long k, const HPixVal &val)
設(shè)置第k個像素值 - virtual void Display(const HWindow &w) const
在一個窗口上顯示圖像
幾何運算
HImage operator & (const HRegion ®) const
裁剪圖像的一部分區(qū)域,然后返回此部分的圖像。同reduce_domain.
點評: 此函數(shù)設(shè)計的還是很好的,比較符合直覺。一幅圖像與區(qū)域做&運算,就是獲取共同的部分,也就是裁剪后的圖像。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 div) const
圖像加減乘除,同scale_imageHRegion 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, seedyn_threshold
點評:動態(tài)閾值,局部閾值處理,一般和均指圖像做比較。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);
}
![][3]
本例首先從文件中讀取一幅灰度圖像,目的是提取暗的部分。截取部分區(qū)域處理只是為了節(jié)省時間。可以通過鼠標任意畫出部分區(qū)域來選擇我們處理的部分圖像區(qū)域。這部分區(qū)域掩模用于作為輸入去截取圖像(運算符&).帶有61x61大小的均指掩模被應(yīng)用于最后截取的圖像獲得均值圖像。暗的像素通過應(yīng)用算子<= 選取。所有的像素不超過均值-3的都選取。 具體可以參考 dyn_threshold.
Pixel Values
HPixVal被用來訪問類HImage的像素值。灰度值可以獨立于他們的類型而返回和設(shè)置。
如下介紹常見的成員函數(shù):
//構(gòu)造
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). //強制轉(zhuǎn)換
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)坐標獲得。
點評: 本例的實質(zhì)是觀察int與HPixVal的隱式轉(zhuǎn)換。首先SetPixVal的第三個參數(shù)應(yīng)該是HPixVal,但是輸入實際上是int,由于類HPixVal提供了HPixVal(int Val)
的構(gòu)造函數(shù),使得隱式轉(zhuǎn)換可以成功。后面GetPixVal獲取像素,又由于類HPixVal提供了operator int(void) const
的轉(zhuǎn)換函數(shù),使得int pix = in.GetPixVal(k);
是有效的。
Image Arrays
同之前定義region的數(shù)組,HImage也定義了其數(shù)組,即HImageArray.
成員函數(shù)如下:
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),對應(yīng)著HByteImage;對于像素類型int2(signed 16 bit),對應(yīng)著HInt2Image。但是使用最廣泛的是HByteImage,基本上覆蓋了圖像處理的大部分領(lǐng)域。HByteImage相對于HImage的優(yōu)點是簡化了像素值的訪問機制。主要是因為HPixVal不再使用。除了HImage的成員函數(shù)外,HByteImage還包含了以下擴展:
像素的設(shè)置和獲得
- HByte &operator[] (long k)
線性設(shè)置第k個像素 - HByte operator[] (long k) const
線性讀取第k個像素 - HByte &operator() (long k)
線性設(shè)置第k個像素 - HByte operator() (long k) const
線性讀取第k個像素 - HByte &operator()(int x, int y)
通過坐標(x,y)設(shè)置像素 - 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)
兩圖像對應(yīng)像素取 & - HByteImage operator | (HByteImage &ima)
兩圖像對應(yīng)像素取 | - HByteImage operator ^ (HByteImage &ima)
兩圖像對應(yīng)像素取 異或
例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的簡稱。這種數(shù)據(jù)結(jié)構(gòu)可以描述areas(即任意大小的區(qū)域或者多邊形)or 任何封閉的或者打開的輪廓。與regions代表像素精度相反,XLD代表的是亞像素精度。其中有兩種基本的XLD結(jié)構(gòu): 輪廓(contours)和 多邊形(polygons).
與圖像相似,HALCON/C++也提供了基類HXLD和一些繼承自HXLD的特殊類,比如HXLDCont用于輪廓,HXLDPoly用于多邊形。另外也存在一個容器類,即HXLDArray.
### Low—Level Iconic Objects
當以面向過程的方式調(diào)用算子時,Hobject可以被用來代表所有的圖像參數(shù),如 an image,a region,an image array.事實上,Hobject是HALCON訪問內(nèi)部數(shù)據(jù)的基類。并且,Hobejct也可作為HObject和HObject繼承類,如HImage的基類。
Hobject有如下的成員函數(shù):
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的對象也可以包含一個圖像數(shù)據(jù)的數(shù)組。但是不幸的是,Hobject沒有特殊的函數(shù)區(qū)增加和選擇數(shù)組成員,取而代之的是,你必須使用“The Tuple Mode”.一節(jié)所描述的算子```gen_empty_obj, concat_obj, select_obj, and count_obj ``` 代替。
[1]: http://oana7cw0r.bkt.clouddn.com/regionarray1.JPG
[2]: http://oana7cw0r.bkt.clouddn.com/regionarray2.JPG
[3]: http://oana7cw0r.bkt.clouddn.com/halcon/%E4%BE%8B6.6.JPG