一、获取halcon图像的指针(C++)
1、若图像为单通道图像,使用算子 GetImagePointer1() 获取单通道图像指针。
2、若图像为多通道图像,使用自定义函数 rgb3_to_interleaved() 将三通道彩色图像转换为具有交错颜色信息的单通道图像(width*3),然后再使用算子 GetImagePointer1()获取单通道图像指针。
3、根据以上2个步骤获取的图像指针和宽高信息,
使用算子GetImagePointer1() 生成单通道图像,
使用算子GenImageInterleaved() 生成多通道图像(width/3),该算子在halcon中有例程,并且其中有该函数 rgb3_to_interleaved() 的实现。
4、以上的3个步骤对应以下代码的3个步骤:
//1. 读取图像,获取图像指针
HObject src, srcGray;
ReadImage(&src, "./pic/3.png");
HTuple hv_Pointer, hv_Type, hv_Width, hv_Height, hv_Channels;
CountChannels(src, &hv_Channels);//获取通道数
if (hv_Channels.I() != 1)
{
// 将三通道彩色图像转换为具有交错颜色信息的单通道图像
rgb3_to_interleaved(src, &srcGray);
//WriteImage(srcGray, "jpg", 0, "srcGray.jpg");
GetImagePointer1(srcGray, &hv_Pointer, &hv_Type, &hv_Width, &hv_Height); //获取单通道图像指针
}
else
{
GetImagePointer1(src, &hv_Pointer, &hv_Type, &hv_Width, &hv_Height);//获取单通道图像指针
}
//2.获取图像信息
Corp_message src_data; //自定义结构体
src_data.img_num = 1;
src_data.src.channels = hv_Channels.I();
src_data.src.imageHeight = hv_Height.I();
src_data.src.imageWidth = hv_Width.I();
src_data.src.image_data = (void*)hv_Pointer.L();
//3. 根据图像信息生成图像
if (src_data.src.channels == 1) //单通道图像生成
{
if ((src_data.src.imageHeight > 1) && (src_data.src.imageWidth > 1) && (src_data.src.image_data != NULL))
{
hImage.GenImage1("byte", src_data.src.imageWidth, src_data.src.imageHeight, src_data.src.image_data);
//hImage.WriteImage("jpg", 0, "1.jpg");
}
hGrayImage = hImage.CopyImage();
}
else //多通道图像生成
{
if ((src_data.src.imageHeight > 1) && (src_data.src.imageWidth > 1) && (src_data.src.image_data != NULL))
{
//hImage.GenImageInterleaved(src_data.src.image_data, "rgb", src_data.src.imageWidth, src_data.src.imageHeight, 0, "byte", src_data.src.imageWidth, src_data.src.imageHeight, 0, 0, 8, 0);
hImage.GenImageInterleaved(src_data.src.image_data, "rgb", src_data.src.imageWidth/3, src_data.src.imageHeight, -1, "byte", 0, 0, 0, 0, -1, 0);
hImage.WriteImage("jpg", 0, "2.jpg");
}
hGrayImage = hImage.Rgb1ToGray();
hGrayImage.WriteImage("jpg", 0, "3.jpg");
}
使用 rgb3_to_interleaved() 将三通道彩色图像转换为具有交错颜色信息的单通道图像:
// 将三通道彩色图像转换为具有交错颜色信息的单通道图像
void rgb3_to_interleaved(HObject ho_ImageRGB, HObject* ho_ImageInterleaved)
{
// Local iconic variables
HObject ho_ImageAffineTrans, ho_ImageRed, ho_ImageGreen;
HObject ho_ImageBlue, ho_RegionGrid, ho_RegionMoved, ho_RegionClipped;
// Local control variables
HTuple hv_PointerRed, hv_PointerGreen, hv_PointerBlue;
HTuple hv_Type, hv_Width, hv_Height, hv_HomMat2DIdentity;
HTuple hv_HomMat2DScale;
GetImagePointer3(ho_ImageRGB, &hv_PointerRed, &hv_PointerGreen, &hv_PointerBlue,
&hv_Type, &hv_Width, &hv_Height);
GenImageConst(&(*ho_ImageInterleaved), "byte", hv_Width * 3, hv_Height);
//
HomMat2dIdentity(&hv_HomMat2DIdentity);
HomMat2dScale(hv_HomMat2DIdentity, 1, 3, 0, 0, &hv_HomMat2DScale);
AffineTransImageSize(ho_ImageRGB, &ho_ImageAffineTrans, hv_HomMat2DScale, "constant",
hv_Width * 3, hv_Height);
//
Decompose3(ho_ImageAffineTrans, &ho_ImageRed, &ho_ImageGreen, &ho_ImageBlue);
GenGridRegion(&ho_RegionGrid, 2 * hv_Height, 3, "lines", hv_Width * 3, hv_Height + 1);
MoveRegion(ho_RegionGrid, &ho_RegionMoved, -1, 0);
ClipRegion(ho_RegionMoved, &ho_RegionClipped, 0, 0, hv_Height - 1, (3 * hv_Width) - 1);
ReduceDomain(ho_ImageRed, ho_RegionClipped, &ho_ImageRed);
MoveRegion(ho_RegionGrid, &ho_RegionMoved, -1, 1);
ClipRegion(ho_RegionMoved, &ho_RegionClipped, 0, 0, hv_Height - 1, (3 * hv_Width) - 1);
ReduceDomain(ho_ImageGreen, ho_RegionClipped, &ho_ImageGreen);
MoveRegion(ho_RegionGrid, &ho_RegionMoved, -1, 2);
ClipRegion(ho_RegionMoved, &ho_RegionClipped, 0, 0, hv_Height - 1, (3 * hv_Width) - 1);
ReduceDomain(ho_ImageBlue, ho_RegionClipped, &ho_ImageBlue);
OverpaintGray((*ho_ImageInterleaved), ho_ImageRed);
OverpaintGray((*ho_ImageInterleaved), ho_ImageGreen);
OverpaintGray((*ho_ImageInterleaved), ho_ImageBlue);
return;
}
二、获取halcon图像的指针(C#)
C#的实现步骤和算子与C++是相同的,只是编程语言不同,下面是代码实现:
HObject src, ho_ImageInterleaved;
HOperatorSet.ReadImage(out src, "./pic/huashang.png"); //读取图像
HTuple hv_Pointer, hv_Type, hv_Width, hv_Height, hv_Channels;
HOperatorSet.CountChannels(src, out hv_Channels); //获取图像通道数
if (hv_Channels.I != 1) //多通道图像指针获取
{
// 将三通道彩色图像转换为具有交错颜色信息的单通道图像(宽度*3)。
rgb3_to_interleaved(src, out ho_ImageInterleaved);
//HOperatorSet.WriteImage(ho_ImageInterleaved, "png", 0, "ho_ImageInterleaved.png");
HOperatorSet.GetImagePointer1(ho_ImageInterleaved, out hv_Pointer, out hv_Type, out hv_Width, out hv_Height);
}
else //单通道图像指针获取
{
HOperatorSet.GetImagePointer1(src, out hv_Pointer, out hv_Type, out hv_Width, out hv_Height);
}
使用 rgb3_to_interleaved() 将三通道彩色图像转换为具有交错颜色信息的单通道图像:
private void rgb3_to_interleaved(HObject ho_ImageRGB, out HObject ho_ImageInterleaved)
{
// Local iconic variables
HObject ho_ImageAffineTrans, ho_ImageRed, ho_ImageGreen;
HObject ho_ImageBlue, ho_RegionGrid, ho_RegionMoved, ho_RegionClipped;
// Local control variables
HTuple hv_PointerRed = new HTuple(), hv_PointerGreen = new HTuple();
HTuple hv_PointerBlue = new HTuple(), hv_Type = new HTuple();
HTuple hv_Width = new HTuple(), hv_Height = new HTuple();
HTuple hv_HomMat2DIdentity = new HTuple(), hv_HomMat2DScale = new HTuple();
// Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(out ho_ImageInterleaved);
HOperatorSet.GenEmptyObj(out ho_ImageAffineTrans);
HOperatorSet.GenEmptyObj(out ho_ImageRed);
HOperatorSet.GenEmptyObj(out ho_ImageGreen);
HOperatorSet.GenEmptyObj(out ho_ImageBlue);
HOperatorSet.GenEmptyObj(out ho_RegionGrid);
HOperatorSet.GenEmptyObj(out ho_RegionMoved);
HOperatorSet.GenEmptyObj(out ho_RegionClipped);
//hv_PointerRed.Dispose(); hv_PointerGreen.Dispose(); hv_PointerBlue.Dispose(); hv_Type.Dispose(); hv_Width.Dispose(); hv_Height.Dispose();
HOperatorSet.GetImagePointer3(ho_ImageRGB, out hv_PointerRed, out hv_PointerGreen,
out hv_PointerBlue, out hv_Type, out hv_Width, out hv_Height);
using (HDevDisposeHelper dh = new HDevDisposeHelper())
{
ho_ImageInterleaved.Dispose();
HOperatorSet.GenImageConst(out ho_ImageInterleaved, "byte", hv_Width * 3, hv_Height);
}
//
//hv_HomMat2DIdentity.Dispose();
HOperatorSet.HomMat2dIdentity(out hv_HomMat2DIdentity);
//hv_HomMat2DScale.Dispose();
HOperatorSet.HomMat2dScale(hv_HomMat2DIdentity, 1, 3, 0, 0, out hv_HomMat2DScale);
using (HDevDisposeHelper dh = new HDevDisposeHelper())
{
ho_ImageAffineTrans.Dispose();
HOperatorSet.AffineTransImageSize(ho_ImageRGB, out ho_ImageAffineTrans, hv_HomMat2DScale,
"constant", hv_Width * 3, hv_Height);
}
//
ho_ImageRed.Dispose(); ho_ImageGreen.Dispose(); ho_ImageBlue.Dispose();
HOperatorSet.Decompose3(ho_ImageAffineTrans, out ho_ImageRed, out ho_ImageGreen,out ho_ImageBlue);
using (HDevDisposeHelper dh = new HDevDisposeHelper())
{
ho_RegionGrid.Dispose();
HOperatorSet.GenGridRegion(out ho_RegionGrid, 2 * hv_Height, 3, "lines", hv_Width * 3,
hv_Height + 1);
}
ho_RegionMoved.Dispose();
HOperatorSet.MoveRegion(ho_RegionGrid, out ho_RegionMoved, -1, 0);
using (HDevDisposeHelper dh = new HDevDisposeHelper())
{
ho_RegionClipped.Dispose();
HOperatorSet.ClipRegion(ho_RegionMoved, out ho_RegionClipped, 0, 0, hv_Height - 1,(3 * hv_Width) - 1);
}
{
HObject ExpTmpOutVar_0;
HOperatorSet.ReduceDomain(ho_ImageRed, ho_RegionClipped, out ExpTmpOutVar_0);
ho_ImageRed.Dispose();
ho_ImageRed = ExpTmpOutVar_0;
}
ho_RegionMoved.Dispose();
HOperatorSet.MoveRegion(ho_RegionGrid, out ho_RegionMoved, -1, 1);
using (HDevDisposeHelper dh = new HDevDisposeHelper())
{
ho_RegionClipped.Dispose();
HOperatorSet.ClipRegion(ho_RegionMoved, out ho_RegionClipped, 0, 0, hv_Height - 1,
(3 * hv_Width) - 1);
}
{
HObject ExpTmpOutVar_0;
HOperatorSet.ReduceDomain(ho_ImageGreen, ho_RegionClipped, out ExpTmpOutVar_0
);
ho_ImageGreen.Dispose();
ho_ImageGreen = ExpTmpOutVar_0;
}
ho_RegionMoved.Dispose();
HOperatorSet.MoveRegion(ho_RegionGrid, out ho_RegionMoved, -1, 2);
using (HDevDisposeHelper dh = new HDevDisposeHelper())
{
ho_RegionClipped.Dispose();
HOperatorSet.ClipRegion(ho_RegionMoved, out ho_RegionClipped, 0, 0, hv_Height - 1,
(3 * hv_Width) - 1);
}
{
HObject ExpTmpOutVar_0;
HOperatorSet.ReduceDomain(ho_ImageBlue, ho_RegionClipped, out ExpTmpOutVar_0);
ho_ImageBlue.Dispose();
ho_ImageBlue = ExpTmpOutVar_0;
}
HOperatorSet.OverpaintGray(ho_ImageInterleaved, ho_ImageRed);
HOperatorSet.OverpaintGray(ho_ImageInterleaved, ho_ImageGreen);
HOperatorSet.OverpaintGray(ho_ImageInterleaved, ho_ImageBlue);
ho_ImageAffineTrans.Dispose();
ho_ImageRed.Dispose();
ho_ImageGreen.Dispose();
ho_ImageBlue.Dispose();
ho_RegionGrid.Dispose();
ho_RegionMoved.Dispose();
ho_RegionClipped.Dispose();
//hv_PointerRed.Dispose();
//hv_PointerGreen.Dispose();
//hv_PointerBlue.Dispose();
//hv_Type.Dispose();
//hv_Width.Dispose();
//hv_Height.Dispose();
//hv_HomMat2DIdentity.Dispose();
//hv_HomMat2DScale.Dispose();
return;
}