Halcon
如何使用 VCVCVCVC 在 Halcon
Halcon
Halcon 中得到像素的信息
作者:支源,时间 2007-3-16
Halcon 的强大功能使我们省去很多图像处理(机器视觉)中的很多麻烦而又重复性的
工作。但是,面向不同的应用,应该编写自己最核心的算法,从而达到最佳的处理效果;而
且 Halcon 并不可能把各种情况都考虑进去。以下是我初步入门 Halcon 和 VC 的一点感触和
想法,已经被实验证明了是正确的。
1,在 VC 中,使用 Halcon 打开图像文件,这里要注意 read_image()和 get_image_pointer1()
指令被 HDevelop 翻译过来以后如下:
Image
Pointer, Type, Width, Height
Hobject
HTuple
get_image_pointer1(Image, &Pointer, &Type, &Width, &Height);
VC 中如下声明:
Halcon::Hobject
Halcon::HTuple
Image
Pointer, Type, Width, Height
VC 中也可以如下声明使用:
Hobject
Char
Hlong
Image
lpcsType[MAX_STRING]
Pointer, Width, Height
或 long Width, Height
(如果定义为 HTuple Pointer ; Hlong Width, Height; 编译会出现错误;
Pointer, Type, Width, Height 的话,后续中需要
使用 Halcon::HTuple
图像的高宽时,强制类型转换不可用;
当然 Hlong 可以换成 long,推荐使用 Hlong。)
get_image_pointer1(Image, &Pointer,
这里注意,在 VC 中如果 get_image_pointer1( )中的字节类型使用 tuple 变量,那么
Width 和 Height 也必须使用 tuple 变量,否则编译时候容易出错误,至于原因是什么,可能
halcon 编译的时候需要各个参数的类型形式一致。
lpcsType, &Width, &Height);
2,tuple 类型的返回指针 Pointer 指向图像数据区域(如果是彩色则指向色彩的第一通
道),图像的 RGB 色彩存放是同一种色彩信号最放在一起。注意 Pointer 所指向区域的大小
比图像必须的色彩信息要大许多,这里可能是因为必须为 tuple 变量定义一定的类型限制,
从而使用的空间变大了(由于不了解 tuple 的内部存储格式,所以不敢断定)。请看下面一段
例子程序:使用 Halcon,把彩色图像转化为灰度图像,然后使用 Pointer 指针得到灰度图像
并显示,包括在 VC 窗口中进行显示部分。
using namespace Halcon;
char lpcsType[MAX_STRING];
Hlong PointerGray,WidthGray, HeightGray;
rgb1_to_gray(objImage, &objImageGray);
get_image_pointer1(objImage, &PointerGray, lpcsType, &WidthGray, &HeightGray);
BYTE * lpByte;
BYTE * ImageGray;
int bytewidth;
bytewidth = ((long) WidthGray * 3 + 3 ) / 4 * 4 ;
ImageGray = NULL ;
ImageGray = new BYTE[ bytewidth * (long) HeightGray];
lpByte = (BYTE *) PointerGray;
int i,j;
for( j = (long)HeightGray-1; j>=0; j--)
{
//(注意tuple中图像数据的存放和VC中的差别)
for( i = 0; i < (long)WidthGray; i++)
{
* (ImageGray + j * bytewidth + i * 3 + 0 ) = * lpByte ;
* (ImageGray + j * bytewidth + i * 3 + 1 ) = * lpByte ;
* (ImageGray + j * bytewidth + i * 3 + 2 ) = * lpByte ;
lpByte++;
}
= sizeof(BITMAPINFOHEADER);
}
BITMAPINFO * RotateBmpInfo;
BYTE * bitBuffer;
bitBuffer = NULL;
bitBuffer = new BYTE[sizeof(BITMAPINFO)];
RotateBmpInfo = (BITMAPINFO *)bitBuffer;
RotateBmpInfo->bmiHeader.biSize
RotateBmpInfo->bmiHeader.biHeight = HeightGray;
RotateBmpInfo->bmiHeader.biWidth = WidthGray;
RotateBmpInfo->bmiHeader.biPlanes = 1;
RotateBmpInfo->bmiHeader.biBitCount
RotateBmpInfo->bmiHeader.biCompression
RotateBmpInfo->bmiHeader.biSizeImage = HeightGray * bytewidth;
RotateBmpInfo->bmiHeader.biXPelsPerMeter= 0;
RotateBmpInfo->bmiHeader.biYPelsPerMeter= 0;
= 0;
RotateBmpInfo->bmiHeader.biClrUsed
RotateBmpInfo->bmiHeader.biClrImportant
= 0;
CWnd * m_pWnd ;
m_pWnd = AfxGetApp()->GetMainWnd();
CDC *ddc = m_pWnd->GetDC();
::StretchDIBits(
= BI_RGB;
= 24;
//注意结合图像像素存储的类型进行定义
ddc->GetSafeHdc(),
WidthGray + 10,
HeightGray + 10,
WidthGray,
HeightGray,
0,
0,
WidthGray,
HeightGray,
ImageGray,
//显示窗口宽度
//显示窗口高度
//图像宽度
//图像高度
RotateBmpInfo,
DIB_RGB_COLORS,
SRCCOPY);
;
m_pWnd->ReleaseDC(ddc)
delete []ImageGray ;
delete []bitBuffer ;
后来实验发现,如果按照 HDevelop 默认翻译过来的规则写 C++程序,如下:
Halcon::Hobject
Halcon::HTuple
操作 get_image_pointer1(objImage, &Pointer, &Type, &Width, &Height)
执行以后,可以使用 Width[0],Height[0]进行数据访问,但是命令:
lpByte = (BYTE *) PointerGray;
不能够执行,作者也在进一步弄清楚如何解决这个问题,请大家给点帮助。
Image
Pointer, Type, Width, Height
今天在调试程序中发现一个问题,再次让我感受Halcon内存管理的神秘,嘿
嘿,说说问题吧
Hlong PointerGray, PointerRed, PointerGreen, PointerBlue;
Hlong WidthGray, HeightGray;
get_image_pointer1(objImageGray, &PointerGray, lpcsType, &WidthGray,
&HeightGray);
编译可以通过,但是
Hlong PointerGray, PointerRed, PointerGreen, PointerBlue;
Hlong WidthGray, HeightGray;
get_image_pointer3(objImage, &PointerRed, &PointerGreen, &PointerBlue,
&lpcsType, &WidthGray, &HeightGray);
编译就通不过,大家可以试一下
如果需要,可以使用 decompose3(objImage, &objImageRed, &objImageGreen,
&objImageGray);
然后使用函数get_image_pointer1()得到指针
我个人认为是Halcon的变量类型讲究统一,如果是Tuple都是Tuple,我个人
认为PointerRed,PointerGreen,PointerBlue可能是Tuple变量中的三个量,而
HeightGray不是按照Tuple变量进行管理的,纯属个人猜测,大家有想法的给我回,
或发邮件zhiyuanshiji@sohu.com或者zhiyuan_maiker@hotmail.com
Halcon
1.1.1.1.从 Halcon
Halcon 到 VC++VC++VC++VC++
Halcon
read_image(&Image,"文件名");//读入的为灰度图像
//获取图像指针,注意输出变量的类型
char lpcsType[MAX_STRING];
Hlong Pointer,Width, Height;
get_image_pointer1(Image, &Pointer, lpcsType, &Width, &Height);
//Halcon 与 VC++中的图像之间,存在着上下翻转
BYTE * lpByte;
BYTE * ImageG;
int bytewidth;
bytewidth = ((long) Width * 3 + 3 ) / 4 * 4 ;
ImageG = NULL ;
ImageG = new BYTE[ bytewidth * (long) Height ];
lpByte = (BYTE *) Pointer;
int i,j;
for( j = (long)Height-1; j>=0; j--)
{
//注意结合图像像素存储的类型进行定义
//(注意 tuple 中图像数据的存放和 VC 中的差别)
for( i = 0; i < (long)WidthGray; i++)
{
* (ImageG + j * bytewidth + i * 3 + 0 ) = * lpByte ;
* (ImageG + j * bytewidth + i * 3 + 1 ) = * lpByte ;
* (ImageG + j * bytewidth + i * 3 + 2 ) = * lpByte ;
lpByte++;
}
}
BITMAPINFO * RotateBmpInfo;
BYTE * bitBuffer;
bitBuffer = NULL;
bitBuffer = new BYTE[sizeof(BITMAPINFO)];
RotateBmpInfo = (BITMAPINFO *)bitBuffer;
RotateBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
RotateBmpInfo->bmiHeader.biHeight
RotateBmpInfo->bmiHeader.biWidth
RotateBmpInfo->bmiHeader.biPlanes
RotateBmpInfo->bmiHeader.biBitCount = 24;
RotateBmpInfo->bmiHeader.biCompression
RotateBmpInfo->bmiHeader.biSizeImage
RotateBmpInfo->bmiHeader.biXPelsPerMeter= 0;
RotateBmpInfo->bmiHeader.biYPelsPerMeter= 0;
RotateBmpInfo->bmiHeader.biClrUsed
RotateBmpInfo->bmiHeader.biClrImportant
CWnd * m_pWnd ;
m_pWnd = AfxGetApp()->GetMainWnd();
CDC *pDC = m_pWnd->GetDC();
= Height;
= Width;
= 1;
= BI_RGB;
= 0;
= 0;
= Height * bytewidth;
::StretchDIBits(
pDC->GetSafeHdc(),
Width + 10,
Height + 10,
Width,
Height,
0,
0,
Width,
Height,
ImageG,
RotateBmpInfo,
DIB_RGB_COLORS,
SRCCOPY);
//显示窗口宽度
//显示窗口高度
//图像宽度
//图像高度
m_pWnd->ReleaseDC(pDC);
delete [] ImageG ;
delete [] bitBuffer ;
2.2.2.2. 从 VC++VC++VC++VC++到 Halcon
Halcon
Halcon
Halcon
unsigned char *Pointer;
int width, height;
Pointer = new unsigned char[width * height];
int i, j;
for (i=0; i
lWWindowID = (Hlong)m_hWnd; //要显示图片的控件的句柄
set_window_attr("border_width",0); //设置窗口属性
set_window_attr("background_color","light gray"); //设置窗口背景颜色
set_check("~father");
open_window(0,0,m_Width,m_Height,lWWindowID,"visible","",&WindowHandle); // 创 建
窗口
set_check("father");
set_part(WindowHandle,0,0,m_Width-1,m_Height-1); //对窗口上显示图像和区域的一些
设置
set_draw(WindowHandle,"margin");
set_colored(WindowHandle,12);
disp_obj(Image,WindowHandle); //显示图像 Image(Hobject 类型)
4.4.4.4.从 HTuple
HTuple
HTuple
HTuple 类型读取数据
//HTuple 有一个元素
HTuple aa = 120;
double dd = aa[0].D(); // dd=120.000
int ii = aa[0].I(); //ii=120
long ll = aa[0].L(); //ll=120
Hlong hh = aa[0].L();//hh=120
long num = aa.Num(); //num =1;
aa = "120"; //HTuple 为字符串时,如果赋值不是字符串,不能调用 S()函数
const char *cc;
cc = aa[0].S(); //cc[0]='1',cc[1]='2',cc[2]='0'
//当 aa 为多元素的数组时
aa[1] = 230;
num = aa.Num(); //num =2;
ii = aa[1].I(); //ii=230
//其他获取数据的方法与上面类似