当前位置:文档之家› Halcon_VC相关

Halcon_VC相关

如何使用VC在Halcon中得到像素的信息作者:支源,时间2007-3-16Halcon的强大功能使我们省去很多图像处理(机器视觉)中的很多麻烦而又重复性的工作。

但是,面向不同的应用,应该编写自己最核心的算法,从而达到最佳的处理效果;而且Halcon并不可能把各种情况都考虑进去。

以下是我初步入门Halcon和VC的一点感触和想法,已经被实验证明了是正确的。

1,在VC中,使用Halcon打开图像文件,这里要注意read_image()和get_image_pointer1()指令被HDevelop翻译过来以后如下:Hobject ImageHTuple Pointer, Type, Width, Heightget_image_pointer1(Image, &Pointer, &Type, &Width, &Height);VC中如下声明:Halcon::Hobject ImageHalcon::HTuple Pointer, Type, Width, HeightVC中也可以如下声明使用:Hobject ImageChar lpcsType[MAX_STRING]Hlong Pointer, Width, Height 或long Width, Height(如果定义为HTuple Pointer ; Hlong Width, Height; 编译会出现错误;使用Halcon::HTuple Pointer, Type, Width, Height的话,后续中需要图像的高宽时,强制类型转换不可用;当然Hlong可以换成long,推荐使用Hlong。

)get_image_pointer1(Image, &Pointer, lpcsType, &Width, &Height);这里注意,在VC中如果get_image_pointer1( )中的字节类型使用tuple变量,那么Width和Height也必须使用tuple变量,否则编译时候容易出错误,至于原因是什么,可能halcon编译的时候需要各个参数的类型形式一致。

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++;}}BITMAPINFO * RotateBmpInfo;BYTE * bitBuffer;bitBuffer = NULL;bitBuffer = new BYTE[sizeof(BITMAPINFO)];RotateBmpInfo = (BITMAPINFO *)bitBuffer;RotateBmpInfo->bmiHeader.biSize= sizeof(BITMAPINFOHEADER); RotateBmpInfo->bmiHeader.biHeight= HeightGray;RotateBmpInfo->bmiHeader.biWidth= WidthGray;RotateBmpInfo->bmiHeader.biPlanes= 1;RotateBmpInfo->bmiHeader.biBitCount= 24;RotateBmpInfo->bmiHeader.biCompression= BI_RGB; RotateBmpInfo->bmiHeader.biSizeImage= HeightGray * bytewidth; RotateBmpInfo->bmiHeader.biXPelsPerMeter= 0;RotateBmpInfo->bmiHeader.biYPelsPerMeter= 0;RotateBmpInfo->bmiHeader.biClrUsed= 0;RotateBmpInfo->bmiHeader.biClrImportant= 0;CWnd * m_pWnd ;m_pWnd = AfxGetApp()->GetMainWnd();CDC *ddc = m_pWnd->GetDC();::StretchDIBits(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 ImageHalcon::HTuple Pointer, Type, Width, Height操作get_image_pointer1(objImage, &Pointer, &Type, &Width, &Height)执行以后,可以使用Width[0],Height[0]进行数据访问,但是命令:lpByte = (BYTE *) PointerGray;不能够执行,作者也在进一步弄清楚如何解决这个问题,请大家给点帮助。

今天在调试程序中发现一个问题,再次让我感受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@或者zhiyuan_maiker@1.从Halcon到VC++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 = Height;RotateBmpInfo->bmiHeader.biWidth = Width;RotateBmpInfo->bmiHeader.biPlanes = 1;RotateBmpInfo->bmiHeader.biBitCount = 24;RotateBmpInfo->bmiHeader.biCompression = BI_RGB; RotateBmpInfo->bmiHeader.biSizeImage = Height * bytewidth; RotateBmpInfo->bmiHeader.biXPelsPerMeter= 0;RotateBmpInfo->bmiHeader.biYPelsPerMeter= 0;RotateBmpInfo->bmiHeader.biClrUsed = 0;RotateBmpInfo->bmiHeader.biClrImportant = 0;CWnd * m_pWnd ;m_pWnd = AfxGetApp()->GetMainWnd();CDC *pDC = m_pWnd->GetDC();::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. 从VC++到Halconunsigned char *Pointer;int width, height;Pointer = new unsigned char[width * height];int i, j;for (i=0; i<height; i++){for (j=0; j<width; j++){Pointer = j % 255;}}Hobject Image;gen_image1_extern(&Image, "byte", (HTuple)width, (HTuple)height, (long)Pointer, NULL);注:a) gen_image1_extern函数中的变量width,height必须为HTuple类型,Pointer指针为unsigned char类型,输入时转换为long型。

相关主题