将点云Z向数据生成伪彩图、灰度图(最小值和最大值区间映射RGB三通道)

C# 指针遍历+for循环多线程

public unsafe static HObject PointXYZ_To_GrayColorHobject(ref PointXYZ[] PointCloudData, int ImgWidth, int ImgHeight, float ZMin, float ZMax,out HObject colorImg)
{
    try
    {
        HObject ImgHobject = null;
        colorImg = null;
        if (PointCloudData == null) return ImgHobject;
        //归一化后按 0-1/3  1/3-2/3  2/3-1 进行颜色映射
        float cut1 = 1.0f / 3.0f;
        float cut2 = 2.0f / 3.0f;
        int numPoints = PointCloudData.Length;
        float RangeZ = ZMax - ZMin;//点云数据范围
        float coefficient = RangeZ > 0 ? 255 * 1.0f / RangeZ : 0;//灰度系数
        //byte[] grayArr = new byte[numPoints];
        IntPtr colorPtr = Marshal.AllocHGlobal(numPoints * 3 * sizeof(byte));//分配伪彩图RGB内存
        IntPtr grayPtr = Marshal.AllocHGlobal(numPoints * sizeof(byte));//分配灰度图内存
        int numProcessedPoints = ImgWidth - (ImgWidth % 4); // 可以处理的点的数量(4的倍数)
        fixed (PointXYZ* pData = PointCloudData)
        {
            float* pHeight = (float*)pData;
            byte* colorPtrTemp = (byte*)colorPtr;
            byte* grayPtrTemp = (byte*)grayPtr;
            Parallel.For(0, ImgHeight, Row =>
            {
                float* PRowIndexPointData = pHeight + Row * ImgWidth * 3;//点云指针
                byte* pDest = colorPtrTemp + Row * 3 * ImgWidth;//伪彩图图像遍历指针
                byte* pGrayDest = grayPtrTemp + Row * ImgWidth;//灰度图图像遍历指针
                for (int Col = 0; Col < numProcessedPoints; Col += 4)
                {
                    float height1 = PRowIndexPointData[2];
                    float height2 = PRowIndexPointData[5];
                    float height3 = PRowIndexPointData[8];
                    float height4 = PRowIndexPointData[11];
                    #region gray灰度映射
                    pGrayDest[0] = (byte)((height1 >= ZMin && height1 <= ZMax) ? (height1 - ZMin) * coefficient : 0);
                    pGrayDest[1] = (byte)((height2 >= ZMin && height2 <= ZMax) ? (height2 - ZMin) * coefficient : 0);
                    pGrayDest[2] = (byte)((height3 >= ZMin && height3 <= ZMax) ? (height3 - ZMin) * coefficient : 0);
                    pGrayDest[3] = (byte)((height4 >= ZMin && height4 <= ZMax) ? (height4 - ZMin) * coefficient : 0);
                    #endregion
                    #region color颜色映射
                    //height1  normalval1
                    if (height1 >= ZMin && height1 <= ZMax)
                    {
                        float normalVal1 = (height1 - ZMin) / RangeZ;
                        if (normalVal1 <= cut1)
                        {
                            pDest[0] = 0;
                            pDest[1] = (byte)(3 * normalVal1 * 255);
                            pDest[2] = 255;
                        }
                        else if (normalVal1 > cut1 && normalVal1 <= cut2)
                        {
                            pDest[0] = (byte)((3 * normalVal1 - 1) * 255);
                            pDest[1] = 255;
                            pDest[2] = (byte)((-3 * normalVal1 + 2) * 255);
                        }
                        else if (normalVal1 > cut2)
                        {
                            pDest[0] = 255;
                            pDest[1] = (byte)((-3 * normalVal1 + 3) * 255);
                            pDest[2] = 0;
                        }
                    }
                    else
                    {
                        pDest[0] = 0;
                        pDest[1] = 0;
                        pDest[2] = 0;
                    }
                    //height2  normalval2
                    if (height2 >= ZMin && height2 <= ZMax)
                    {
                        float normalVal2 = (height2 - ZMin) / RangeZ;
                        if (normalVal2 <= cut1)
                        {
                            pDest[3] = 0;
                            pDest[4] = (byte)(3 * normalVal2 * 255);
                            pDest[5] = 255;
                        }
                        else if (normalVal2 > cut1 && normalVal2 <= cut2)
                        {
                            pDest[3] = (byte)((3 * normalVal2 - 1) * 255);
                            pDest[4] = 255;
                            pDest[5] = (byte)((-3 * normalVal2 + 2) * 255);
                        }
                        else if (normalVal2 > cut2)
                        {
                            pDest[3] = 255;
                            pDest[4] = (byte)((-3 * normalVal2 + 3) * 255);
                            pDest[5] = 0;
                        }
                    }
                    else
                    {
                        pDest[3] = 0;
                        pDest[4] = 0;
                        pDest[5] = 0;
                    }
                    //height3  normalval3
                    if (height3 >= ZMin && height3 <= ZMax)
                    {
                        float normalVal3 = (height3 - ZMin) / RangeZ;
                        if (normalVal3 <= cut1)
                        {
                            pDest[6] = 0;
                            pDest[7] = (byte)(3 * normalVal3 * 255);
                            pDest[8] = 255;
                        }
                        else if (normalVal3 > cut1 && normalVal3 <= cut2)
                        {
                            pDest[6] = (byte)((3 * normalVal3 - 1) * 255);
                            pDest[7] = 255;
                            pDest[8] = (byte)((-3 * normalVal3 + 2) * 255);
                        }
                        else if (normalVal3 > cut2)
                        {
                            pDest[6] = 255;
                            pDest[7] = (byte)((-3 * normalVal3 + 3) * 255);
                            pDest[8] = 0;
                        }
                    }
                    else
                    {
                        pDest[6] = 0;
                        pDest[7] = 0;
                        pDest[8] = 0;
                    }
                    //height4  normalval4
                    if (height4 >= ZMin && height4 <= ZMax)
                    {
                        float normalVal4 = (height4 - ZMin) / RangeZ;
                        if (normalVal4 <= cut1)
                        {
                            pDest[9] = 0;
                            pDest[10] = (byte)(3 * normalVal4 * 255);
                            pDest[11] = 255;
                        }
                        else if (normalVal4 > cut1 && normalVal4 <= cut2)
                        {
                            pDest[9] = (byte)((3 * normalVal4 - 1) * 255);
                            pDest[10] = 255;
                            pDest[11] = (byte)((-3 * normalVal4 + 2) * 255);
                        }
                        else if (normalVal4 > cut2)
                        {
                            pDest[9] = 255;
                            pDest[10] = (byte)((-3 * normalVal4 + 3) * 255);
                            pDest[11] = 0;
                        }
                    }
                    else
                    {
                        pDest[9] = 0;
                        pDest[10] = 0;
                        pDest[11] = 0;
                    }
                    #endregion
                    pGrayDest += 4;
                    pDest += 12;
                    PRowIndexPointData += 12;
                }
                for (int Col = numProcessedPoints; Col < ImgWidth; Col++)
                {
                    float height1 = PRowIndexPointData[2];
                    #region gray灰度映射
                    pGrayDest[0] = (byte)((height1 >= ZMin && height1 <= ZMax) ? (height1 - ZMin) * coefficient : 0);
                    #endregion
                    #region color颜色映射
                    //height1  normalval1
                    if (height1 >= ZMin && height1 <= ZMax)
                    {
                        float normalVal1 = (height1 - ZMin) / RangeZ;
                        if (normalVal1 <= cut1)
                        {
                            pDest[0] = 0;
                            pDest[1] = (byte)(3 * normalVal1 * 255);
                            pDest[2] = 255;
                        }
                        else if (normalVal1 > cut1 && normalVal1 <= cut2)
                        {
                            pDest[0] = (byte)((3 * normalVal1 - 1) * 255);
                            pDest[1] = 255;
                            pDest[2] = (byte)((-3 * normalVal1 + 2) * 255);
                        }
                        else if (normalVal1 > cut2)
                        {
                            pDest[0] = 255;
                            pDest[1] = (byte)((-3 * normalVal1 + 3) * 255);
                            pDest[2] = 0;
                        }
                    }
                    else
                    {
                        pDest[0] = 0;
                        pDest[1] = 0;
                        pDest[2] = 0;
                    }
                    #endregion
                    pGrayDest++;
                    pDest += 3;
                    PRowIndexPointData += 3;
                }
            });
        }
        HOperatorSet.GenImage1(out ImgHobject, "byte", ImgWidth, ImgHeight, grayPtr);
        HOperatorSet.GenImageInterleaved(out colorImg, colorPtr, "rgb", ImgWidth, ImgHeight, -1, "byte", ImgWidth, ImgHeight, 0, 0, -1, 0);
        Marshal.FreeHGlobal(colorPtr);
        Marshal.FreeHGlobal(grayPtr);
        return ImgHobject;
    }
    catch
    {
        colorImg = null;
        return null;
    }
}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

beyond951

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值