网站开发制作熊掌号电脑大型网络游戏排行
网站开发制作熊掌号,电脑大型网络游戏排行,东台市住房和建设局网站,网站风格对比以下是 ImageToTensor 函数的完整实现版本#xff0c;專門用在 .NET MAUI YOLOv8 ONNX 推理流程中#xff0c;將 SkiaSharp 的 SKBitmap 轉換成 ONNX Runtime 需要的 DenseTensor#xff08;形狀通常為 [1, 3, 640, 640] 或你模型的輸入尺寸#xff09;。
這個函數實現了 …以下是ImageToTensor函数的完整实现版本專門用在 .NET MAUI YOLOv8 ONNX 推理流程中將 SkiaSharp 的 SKBitmap 轉換成 ONNX Runtime 需要的DenseTensor形狀通常為 [1, 3, 640, 640] 或你模型的輸入尺寸。這個函數實現了 YOLOv8 最常見的預處理步驟BGR → RGB如果來源是 BGR縮放到模型輸入尺寸通常 640×640歸一化到 [0,1]像素值 / 255通道順序轉為 CHWC3, H640, W640增加 batch 維度 [1, 3, H, W]推薦實現最常用版本usingMicrosoft.ML.OnnxRuntime.Tensors;usingSkiaSharp;/// summary/// 將 SKBitmap 轉換為 YOLOv8 ONNX 模型所需的輸入 Tensor/// 輸入形狀[1, 3, height, width]通道順序 CHW值域 [0,1]/// /summary/// param namebitmap原始或已 resize 的 SKBitmap建議已 resize 到模型輸入尺寸/param/// param nametargetWidth模型期望的寬度通常 640/param/// param nametargetHeight模型期望的高度通常 640/param/// returnsDenseTensorlt;floatgt; 供 ONNX Runtime 使用/returnsprivateDenseTensorfloatImageToTensor(SKBitmapbitmap,inttargetWidth640,inttargetHeight640){// 如果輸入圖片尺寸不匹配先 resize保持比例 填充黑邊 或 直接強制拉伸// 這裡採用最常見的強制 resize 到 640x640YOLOv8 訓練時多為此方式usingvarresizedbitmap.Resize(newSKImageInfo(targetWidth,targetHeight),SKFilterQuality.High);// 創建輸出 Tensor[1, 3, H, W]vartensornewDenseTensorfloat(new[]{1,3,targetHeight,targetWidth});// 遍歷每個像素進行通道重排 歸一化for(inty0;ytargetHeight;y){for(intx0;xtargetWidth;x){// 獲取像素顏色SkiaSharp 是 RGBA 格式SKColorpixelresized.GetPixel(x,y);// 轉換為 RGBYOLOv8 期望 RGB 順序floatrpixel.Red/255f;floatgpixel.Green/255f;floatbpixel.Blue/255f;// CHW 佈局先通道再高度再寬度// channel 0 R, channel 1 G, channel 2 Btensor[0,0,y,x]r;// Rtensor[0,1,y,x]g;// Gtensor[0,2,y,x]b;// B}}returntensor;}更高效版本使用 Span 內存複製推薦生產環境如果你在意性能尤其是移動端可以用 Span 避免逐像素 GetPixel/SetPixel 的開銷privateDenseTensorfloatImageToTensorFast(SKBitmapbitmap,inttargetWidth640,inttargetHeight640){usingvarresizedbitmap.Resize(newSKImageInfo(targetWidth,targetHeight),SKFilterQuality.Medium);// 鎖定像素內存usingvarpixmapresized.PeekPixels();if(pixmapnull)thrownewInvalidOperationException(無法獲取像素內存);vartensornewDenseTensorfloat(new[]{1,3,targetHeight,targetWidth});// 獲取原始像素數據RGBA 格式每像素 4 bytesReadOnlySpanbytepixelspixmap.GetPixelSpan();intstridepixmap.RowBytes;// 每行字节數通常 width * 4for(inty0;ytargetHeight;y){introwOffsety*stride;for(intx0;xtargetWidth;x){intpixelOffsetrowOffsetx*4;floatrpixels[pixelOffset0]/255f;// R (假設 RGBA)floatgpixels[pixelOffset1]/255f;// Gfloatbpixels[pixelOffset2]/255f;// B// pixels[pixelOffset 3] 是 Alpha通常忽略tensor[0,0,y,x]r;tensor[0,1,y,x]g;tensor[0,2,y,x]b;}}returntensor;}使用方式在 DetectAsync 中調用publicasyncTaskListDetectionResultDetectAsync(byte[]imageData,intorigWidth,intorigHeight){usingvarskBmpSKBitmap.Decode(imageData);if(skBmpnull)thrownewArgumentException(圖片解碼失敗);varinputTensorImageToTensorFast(skBmp,640,640);varinputsnew[]{NamedOnnxValue.CreateFromTensor(images,inputTensor)};usingvarresultsawaitTask.Run(()_session.Run(inputs));returnYoloV8PostProcess.ProcessOutput(results.First().AsTensorfloat(),origWidth,origHeight,0.4f,0.45f,_labels);}常見變體與注意事項需求修改方式保持長寬比 黑邊填充先計算 scaleresize 後在 tensor 中填充 0paddingLetterboxYOLO 官方推薦計算 scaleresize 後把圖片貼到 640×640 中央周圍填 114灰色BGR 輸入模型把 R 和 B 通道交換順序tensor[0,0,y,x] b; tensor[0,2,y,x] r輸入尺寸不是 640改 targetWidth/targetHeight 即可需匹配導出的 ONNX 模型輸入形狀批量推理改 tensor 第一維為 batch size同時處理多張圖推薦 Letterbox 灰色填充最接近 Ultralytics 官方預處理如果你希望與 Python Ultralytics 的預處理完全一致可以加入 letterbox 邏輯// 先計算縮放比例與填充floatscaleMath.Min((float)targetWidth/bitmap.Width,(float)targetHeight/bitmap.Height);intnewW(int)(bitmap.Width*scale);intnewH(int)(bitmap.Height*scale);usingvarscaledbitmap.Resize(newSKImageInfo(newW,newH),SKFilterQuality.High);// 創建 640x640 畫布背景灰色 (114,114,114)usingvarcanvasBmpnewSKBitmap(targetWidth,targetHeight);usingvarcanvasnewSKCanvas(canvasBmp);canvas.Clear(newSKColor(114,114,114));// 居中貼上縮放後的圖片intpadLeft(targetWidth-newW)/2;intpadTop(targetHeight-newH)/2;canvas.DrawBitmap(scaled,padLeft,padTop);// 再轉 TensorvartensorImageToTensor(canvasBmp,targetWidth,targetHeight);這樣處理後檢測結果的座標需要反向映射回原始圖片尺寸考慮 scale 和 padding。如果你需要這個反向映射的代碼或是想處理 letterbox 的完整前後處理流程可以再告訴我我幫你補上完整版本。