Halcon图像的指针获取与图像生成

本文介绍了如何在C++和C#中使用Halcon库获取图像的指针,特别是针对单通道和多通道图像的处理。通过算子GetImagePointer1和自定义函数rgb3_to_interleaved,将三通道彩色图像转换为单通道图像,以便进行进一步的图像操作。代码示例详细展示了读取图像、转换图像以及生成新图像的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、获取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;
        }
### Halcon `GenImageInterleaved` 函数详解 #### 函数定义 `GenImageInterleaved` 是用于生成多通道图像的功能。该函数允许用户指定不同颜色分量的数据来构建一个多通道的图像对象。 #### 参数描述 - **ChannelData** (输入控制):包含各通道像素值的一维数组或多行一列矩阵。 - **Channels** (输入控制):字符串列表,表示各个通道的颜色名称(如 "red", "green", "blue")。支持的标准通道名有:"gray", "red", "green", "blue", "alpha", "hue", "saturation", "value". - **Width** (输入控制):图像宽度。 - **Height** (输入控制):图像高度。 - **Image** (输出):生成的多通道图像对象。 此函数特别适用于从外部源读取彩色或其他类型的多通道图像数据,并将其转换成可以在 HALCON 中进一步处理的形式[^1]。 #### 示例代码 下面是一个简单的 Python 脚本示例,展示了如何利用 HALCON 的 `gen_image_interleaved()` 方法创建一个 RGB 图像: ```python from pyhalcon import * # 初始化HALCON环境 set_system('no_message_dialog', 'true') # 定义每个通道的数据(这里简化为随机数) width, height = 200, 150 channel_data = [] for _ in range(height * width): channel_data.extend([random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)]) # 创建RGB图像 image_rgb = gen_image_interleaved(channel_data, ['red', 'green', 'blue'], width, height) # 显示图像 disp_obj(image_rgb, get_window_attr('window')) ``` 上述脚本首先设置了 HALCON 不弹出消息对话框;接着准备了一些模拟的色彩数据作为三个独立的通道;最后调用了 `gen_image_interleaved()` 来组合这些数据形成一张完整的 RGB 彩色图片并显示出来。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值