Я читаю файл TiledExr следующим образом, используя C ++ и OpenEXR
std::vector<double> TiledExrDepthMapExtractor::extractDepthMap(const char* filePath,
int& width, int& height, ProgressFunc& progressCallback, ErrorFunc& errorCallback)
{
// Do some stuff then...
return pixelVector;
}
Это вызывается из C#
public class ExrDepthMapExtractor : IDepthMapExtractor
{
public RawDepthMap GetDepthMap(string filePath)
{
return ExtractRawDepthMap(filePath, Callbacks.ProgressCallback, Callbacks.ErrorCallback);
}
private unsafe RawDepthMap ExtractRawDepthMap(string filePath,
Callbacks.ProgressFunc progressCallback, Callbacks.ErrorFunc errorCallback)
{
using (InternalExtractRawDepthMapWrapper(filePath, out RawDepthMap rdm, progressCallback, errorCallback))
{
rdm.Source = filePath;
return rdm;
}
}
private unsafe PixelVectorSafeHandle InternalExtractRawDepthMapWrapper(
string filePath, out RawDepthMap rdm, Callbacks.ProgressFunc progressCallback, Callbacks.ErrorFunc errorCallback)
{
if (!NativeMethods.ExtractDepthMapAs1DArray(out PixelVectorSafeHandle pixelVectorHandle,
out double* pixels, out int width, out int height, filePath, progressCallback))
throw new FormatException($"Depth map could not be extracted from \"{filePath}\"");
var pixelList = new List<double>();
for (int i = 0; i < width * height; i++)
pixelList.Add(pixels[i]);
rdm = new RawDepthMap()
{
Source = filePath,
DepthMapArray = pixelList,
Height = height,
Width = width
};
return pixelVectorHandle;
}
}
Через API
[SuppressUnmanagedCodeSecurity()]
internal static class NativeMethods
{
[DllImport("Blundergat.OpenExr.Adapter.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
internal static unsafe extern bool ExtractDepthMapAs1DArray(
out PixelVectorSafeHandle vectorHandle,
out double* points,
out int width,
out int height,
string filePath,
Callbacks.ProgressFunc progressCallback);
[DllImport("Blundergat.OpenExr.Adapter.dll", CallingConvention = CallingConvention.Cdecl)]
internal static unsafe extern bool Release(IntPtr itemsHandle);
}
и преобразуется в RawDepthMap
public class RawDepthMap
{
public string Source { get; set; }
public List<double> DepthMapArray { get; set; }
public int Height { get; set; }
public int Width { get; set; }
public override string ToString()
{
string source = !String.IsNullOrEmpty(Source) ? Source : "N/A";
StringBuilder builder = new StringBuilder($"RawDepthMap: Source \"{source}\"");
if (DepthMapArray != null)
builder.Append($", Array size {DepthMapArray:N0}");
builder.Append($", Width {Width:N0}, Height {Height:N0}");
return builder.ToString();
}
}
Это сферическая карта глубины (это сферическое панорамное изображение), по сути, одномерный массив измерений глубины. Исходя из этого, я конвертирую в декартовое облако точек, используя
public class DepthMapToPointCloudAdapter : IDepthMapToPointCloudAdapter
{
public DepthMapToPointCloudAdapter() { }
public IPointCloud GetPointCloudFromDepthMap(RawDepthMap rdm)
{
// Do some transformations.
return new PointCloud(dataPoints.ToArray(), rdm.Source);
}
}
Это дает следующее облако точек
Теперь мне нужно прочитать файл EXR изображения. Я делаю это снова, как описано выше, используя C ++
std::vector<double> ImageExrDepthMapExtractor::extractDepthMap(const char* filePath,
int& width, int& height, ProgressFunc& progressCallback, ErrorFunc& errorCallback)
{
// Do some reading...
return pixelVector;
}
Та же процедура преобразования в декартову PointCloud
, но на этот раз я получаю сферическую геометрию.
Это явно связано с тем, как я читаю файл изображения (RGBA) .exr, но что именно вызывает это?