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;
}
}