ITPub博客

首页 > 大数据 > ELK > 在FastAPI应用中使用 (main.py)

在FastAPI应用中使用 (main.py)

投稿 ELK 作者:ecclw459 时间:2026-01-27 20:33:59 0 删除 编辑

rom fastapi import FastAPI, Depends, HTTPException from cache import cache, cached import asyncio app = FastAPI(title=“FastAPI Redis缓存演示”) # 应用启动和关闭事件 @app.on_event( “startup”) async def startup_event ():     await cache.connect()     print (“✅ Redis connected”) @app.on_event( “shutdown”) async def shutdown_event ():     await cache.disconnect()     print (“👋 Redis disconnected”) # --- 模拟一个耗时的数据查询函数 --- async def fetch_user_data_from_db ( user_id: int ):     """模拟从数据库查询用户数据(耗时操作)"""     await asyncio.sleep( 2 )   # 模拟2秒的IO延迟     return {“ id ”: user_id, “name”: f“用户_{user_id}”, “score”: user_id * 10 } # --- 应用缓存的接口 --- @app.get( “/user/{user_id}”) @cached( ttl= 30)   # 为此接口单独设置30秒缓存 async def get_user ( user_id: int ):     """获取用户信息(带缓存)"""    data = await fetch_user_data_from_db(user_id)     return {“source”: “database (cached later)”, “data”: data} @app.get( “/user/{user_id}/fresh”) async def get_user_fresh ( user_id: int ):     """获取用户信息(强制查数据库,不缓存)"""    data = await fetch_user_data_from_db(user_id)     return {“source”: “database (fresh)”, “data”: data} @app.delete( “/cache/user/{user_id}”) async def delete_user_cache ( user_id: int ):     """手动删除某个用户的缓存"""     # 注意:这里需要模拟生成和接口一致的缓存键,实战中可能需要更复杂的键管理    key_pattern = f“fastapi_cache:get_user:{user_id}”    deleted = await cache.delete(key_pattern)     if deleted:         return {“message”: f”Cache for user {user_id} deleted.”}     raise HTTPException(status_code= 404 , detail=“Cache key not found”) if __name__ == “__main__”:     import uvicorn


{if (!File.Exists(imagePath))
    {
        Console.WriteLine("文件不存在!");
        Console.ReadKey();return;
    }try
    {
        Console.WriteLine($"处理:m.114dhz.cn {Path.GetFileName(imagePath)}");var stopwatch = Stopwatch.StartNew();// 检测面单var results = _detector.DetectLabels(imagePath);
        stopwatch.Stop();
        Console.WriteLine($"检测耗时: {stopwatch.ElapsedMilliseconds}ms");
        Console.WriteLine($"找到 {results.Count} 个面单区域");if (results.Count == 0)
        {
            Console.WriteLine("未检测到面单!");
            Console.ReadKey();njsydq.cnreturn;
        }// 显示结果foreach (var result in results)
        {
            Console.WriteLine($"- {result.DetectionMethod}: 置信度 {result.Confidence:F2}, " +$"位置 [{result.BoundingBox.X}, {result.BoundingBox.Y}, " +$"{result.BoundingBox.Width}, {result.BoundingBox.Height}]");
        }// 创建输出目录var outputDir = _config.OutputDirectory;if (!Directory.Exists(outputDir))
            Directory.CreateDirectory(outputDir);var baseName = Path.GetFileNameWithoutExtension(imagePath);// 保存可视化结果if (_config.SaveVisualized)
        {using (var original = new Bitmap(imagePath))
            {
                Bitmap bitResult = ImageProcessor.DrawBoundingBoxesSafe(original, results);var visPath = Path.Combine(outputDir, $"{baseName}_detected.png");
                ImageProcessor.SaveImage(bitResult, visPath);
                Console.WriteLine($"可视化结果已保存: {visPath}");
            }
        }// 保存抠图结果 if (_config.SaveCropped)
        {using (var mat = Cv2.ImRead(imagePath))
            {for (int i = 0; i < results.Count; i++)
                {var cropped = _detector.CropLabel(mat, results[i].BoundingBox);if (cropped != null)
                    {// 图像增强
                        _detector.EnhanceImage(ref cropped);var cropPath = Path.Combine(outputDir, $"{baseName}_label_{i + 1}.png");
                        Console.WriteLine(cropped);
                        ImageProcessor.SaveImage(cropped, cropPath);
                        Console.WriteLine($"抠图已保存: {cropPath}");
                        cropped.Dispose();
                    }
                }
            }
        }// 保存检测结果到JSON
        SaveResultsToJson(results, Path.Combine(outputDir, $"{baseName}_results.json"));
        Console.WriteLine("\n处理完成! 按任意键继续..."); 
    }catch (Exception ex)
    {
        Console.WriteLine($"处理失败: {ex.Message}");
    }

public List<DetectionResult> DetectLabels(string imagePath)
    {var results = new List<DetectionResult>();using (var mat = Cv2.ImRead(imagePath, OpenCvSharp.ImreadModes.Color))
        {if (mat.Empty())
thrownew FileNotFoundException($"无法加载图像: {imagePath}");// 方法1: 轮廓检测var contourResults = DetectByContours(mat);
            results.AddRange(contourResults)wap.jrwsh.com;// 方法2: 颜色检测var colorResults = DetectByColor(mat);
            results.AddRange(colorResults);// 方法3: 边缘检测var edgeResults = DetectByEdges(mat);
            results.AddRange(edgeResults);


   {var results = new List<DetectionResult>(); 
using (var gray = new OpenCvSharp.Mat())using (var binary = new OpenCvSharp.Mat())
        {
            Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);// 二值化
            Cv2.Threshold(gray, binary, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);// 形态学操作var kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3));
            Cv2.MorphologyEx(binary, binary, MorphTypes.Close, kernel);// 查找轮廓            Cv2.FindContours(binary, outvar contours, outvar hierarchy,
                RetrievalModes.External, ContourApproximationModes.ApproxSimple);foreach (var contour in contours)
            {var area =hnsgzxh.com Cv2.ContourArea(contour); 
if (area < _minArea || area > _maxArea)continue;
                Console.WriteLine($"面积:{area}");var rect = Cv2.BoundingRect(contour);// 计算宽高比var aspectRatio = (double)rect.Width / rect.Height;// 面单通常为矩形,宽高比在一定范围内if (aspectRatio > 0.5 && aspectRatio < 3.0)
                {// 计算矩形度var rectArea = rect.Width * rect.Height;var rectangularity = area / rectArea;
Console.WriteLine(rectangularity) weajoy.com;if (rectangularity > 0.55)
                    {
                        results.Add(new DetectionResult
                        {
                            BoundingBox = rect.ToRectangle(),
                            Confidence = rectangularity,
                            DetectionMethod = "Contour"
                        });


private List<DetectionResult> DetectByColor(OpenCvSharp.Mat src)
    {var results = new List<DetectionResult>();using (var hsv = new OpenCvSharp.Mat())using (var mask = new OpenCvSharp.Mat())
        {// 转换到HSV色彩空间            Cv2.CvtColor(src, hsv, ColorConversionCodes.BGR2HSV);// 定义白色/浅色范围var lowerWhite1 = new Scalar(0, 0, 200);var upperWhite1 = new Scalar(180, 30, 255);var lowerWhite2 = new Scalar(0, 0, 180);var upperWhite2 = new Scalar(180, 80, 255);using (var mask1 = new OpenCvSharp.Mat())using (var mask2 = new OpenCvSharp.Mat())
            {
                Cv2.InRange(hsv, lowerWhite1, upperWhite1, mask1);
                Cv2.InRange(hsv, lowerWhite2, upperWhite2, mask2);
                Cv2.BitwiseOr(mask1, mask2, mask);
            }// 形态学操作var kernel njsydq.cn= Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5));
            Cv2.MorphologyEx(mask, mask, MorphTypes.Close, kernel);
            Cv2.MorphologyEx(mask, mask, MorphTypes.Open, kernel);// 查找轮廓            Cv2.FindContours(mask, outvar contours, outvar hierarchy,
                RetrievalModes.External, ContourApproximationModes.ApproxSimple);foreach (var contour in contours)
            {var area = Cv2.ContourArea(contour);if (area < _minArea || area > _maxArea)continue;var rect = Cv2.BoundingRect(contour);// 计算颜色均匀度var uniformity = CalculateColorUniformity(src, rect);if (uniformity > _confidenceThreshold)
                {
                    results.Add(new DetectionResult
                    {
                        BoundingBox = rect.ToRectangle(),
                        Confidence = uniformity,
                        DetectionMethod = "Color"
                    });
                }
            }
        }return results;
    }3.边缘检测private List<DetectionResult> DetectByEdges(OpenCvSharp.Mat src)
    {var results = new List<DetectionResult>();using (var gray = new OpenCvSharp.Mat())using (var edges = new OpenCvSharp.Mat())
        {
            Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);// 降噪
            Cv2.GaussianBlur(gray, gray, new OpenCvSharp.Size(5, 5), 1.5);// 边缘检测
            Cv2.Canny(gray, edges, 50, 150);// 膨胀var kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3));
            Cv2.Dilate(edges, edges, kernel, iterations: 2);// 查找轮廓            Cv2.FindContours(edges, outvar contours, outvar hierarchy,
                RetrievalModes.External, ContourApproximationModes.ApproxSimple);foreach (var contour in contours)
            {var area = Cv2.ContourArea(contour);if (area < _minArea || area > _maxArea)continue;var rect = Cv2.BoundingRect(contour);// 计算边缘密度using (var roi = new OpenCvSharp.Mat(edges, rect))
                {var totalPixels =byven.com roi.Rows * roi.Cols;var edgePixels = Cv2.CountNonZero(roi);var edgeDensity = (double)edgePixels / totalPixels;if (edgeDensity > 0.1 && rect.Width > 100 && rect.Height > 100)
                    {
                        results.Add(new DetectionResult
                        {
                            BoundingBox = rect.ToRectangle(),
                            Confidence = edgeDensity,


// 返回面单图片///</summary>///<param name="errorMsg">异常信息</param>///<param name="IsEnhanceImage">面单是否增强</param>///<param name="IsSaveLocl">是否本地保存</param>///<returns></returns>public Bitmap GetLabelImageByBitmap(outstring errorMsg, bool IsEnhanceImage = true, bool IsSaveLocl = true)
 {
     Bitmap croppedImage fjzhongxiang.cn= null;
     errorMsg = string.Empty; byven.com    try
     {         if (!File.Exists(imagePath))
         {
             ShellLine.WriteLine($"请确保 {imagePath} 存在");
             errorMsg = $"请确保 {imagePath} 存在";
             returnnew Bitmap(10, 10);
         }         //图片目录
         string imageDir = Path.GetDirectoryName(debugImagePath);         if (Directory.Exists(imageDir))
         {
             Directory.CreateDirectory(imageDir);
         }
         Bitmap bitmap1 Lyyqhb.cn= new Bitmap(imagePath);         var rr = oCR.GetOCRDataStr(bitmap1, debugImagePath);         // 读取JSON文件
         string jsonFilePath = imageDir + "\\content.json";         if (!File.Exists(jsonFilePath))
         {
             errorMsg = $"未找到JSON文件,请确保 {jsonFilePath} 存在";
             ShellLine.WriteLine($"未找到JSON文件,请确保 {jsonFilePath} 存在");
             returnnew Bitmap(imagePath);
         }         string preRotatedImage Lyyqhb.cn= imageDir + "\\preRotatedImg.jpg";         if (!File.Exists(preRotatedImage))
         {
             errorMsg = $"未找到面单文件,请确保包裹面单清晰且存在";
             ShellLine.WriteLine($"未找到面单文件,请确保包裹面单清晰且存在");
             returnnew Bitmap(imagePath);
         }         // 解析矩形数据并计算最小外接矩形
         List<Rectangle> rectangles = ParseRectanglesFromJson(jsonFilePath);         if (rectangles.Count == 0)
         {
             errorMsg = "未在JSON文件中找到有效的矩形数据";
             ShellLine.WriteLine("未在JSON文件中找到有效的矩形数据");
             returnnew Bitmap(imagePath);
         }
         Rectangle boundingRect = CalculateBoundingRectangle(rectangles);
         ShellLine.WriteLine($"最小外接矩形: X={boundingRect.X}, Y={boundingRect.Y}, Width={boundingRect.Width}, Height={boundingRect.Height}");
         ShellLine.WriteLine($"包含 {rectangles.Count} 个元素");         // 加载图片并进行裁剪
         using (Bitmap originalImage = new Bitmap(preRotatedImage))
         {             // 确保矩形在图片范围内
             Rectangle safeRect = GetSafeRectangle(boundingRect, originalImage);             // 裁剪图片
             croppedImage jntmjq.cn= CropImage(originalImage, safeRect);             if (IsEnhanceImage)
             {                 // 增强显示 
                 EnhanceImage(ref croppedImage);
             }             if (IsSaveLocl)
             {                 // 保存结果
                 string outputPath = Path.Combine(
                     Path.GetDirectoryName(preRotatedImage),
                     Path.GetFileNameWithoutExtension(preRotatedImage) + "_cropped_enhanced.jpg");
                 croppedImage.Save(outputPath, ImageFormat.Jpeg);
                 ShellLine.WriteLine($"处理完成!结果已保存到: {outputPath}");
             }             // 显示裁剪区域信息
             ShellLine.WriteLine($"\n裁剪区域信息:");
             ShellLine.WriteLine($"  原始图片尺寸: {originalImage.Width}x{originalImage.Height}");
             ShellLine.WriteLine($"  裁剪区域: {safeRect.X}, {safeRect.Y}, {safeRect.Width}x{safeRect.Height}");
             ShellLine.WriteLine($"  增强后图片尺寸: {croppedImage.Width}x{croppedImage.Height}");             return croppedImage;
         }
     }     catch (Exception ex)
     {
         errorMsg = $"处理过程中出现错误: {ex.Message}";
         ShellLine.WriteLine($"处理过程中出现错误: {ex.Message}");
         ShellLine.WriteLine($"堆栈跟踪: {ex.StackTrace}");
         returnnew Bitmap(imagePath);
     }
publicvoidEnhanceImage(ref Bitmap image)
 {     using (var mat = image.ToMat())     using (var lab = new OpenCvSharp.Mat())
     {         // 转换为Lab色彩空间         Cv2.CvtColor(mat, lab, ColorConversionCodes.BGR2Lab);
         Cv2.Split(lab, outvar labChannels);         // 对亮度通道进行直方图均衡化
         Cv2.EqualizeHist(labChannels[0], labChannels[0]);
         Cv2.Merge(labChannels,jntmjq.cn lab);
         Cv2.CvtColor(lab, mat, ColorConversionCodes.Lab2BGR);         // 释放通道
         foreach (var channel in labChannels)
             channel.Dispose();         // 更新图像


static Rectangle CalculateBoundingRectangle(List<Rectangle> rectangles)
  {      if (rectangles.Count == 0)
          thrownew ArgumentException("矩形列表为空");      int minX = int.MaxValue;      int minY = int.MaxValue;      int maxX = int.MinValue;      int maxY = int.MinValue;      foreach (Rectangle rect in rectangles)
      {
          minX yfiso9000.com= Math.Min(minX, rect.X);
          minY = Math.Min(minY, rect.Y);
          maxX = Math.Max(maxX, rect.X + rect.Width);
          maxY = Math.Max(maxY, rect.Y + rect.Height);
      }      // 添加一些边距,使裁剪更美观
      int margin = 10;
      minX = Math.Max(0, minX - margin);
      minY = Math.Max(0, minY - margin);
      maxX = maxX + margin;
      maxY = maxY + margin;
      returnnew Rectangle(minX, minY, maxX - minX, maxY - minY);
  }// 确保矩形在图片范围内static Rectangle GetSafeRectangle(Rectangle rect, Bitmap image)
  {      int x yfiso9000.com=jntmjq.cn Math.Max(0, Math.Min(rect.X, image.Width - 1));      int y = Math.Max(0, Math.Min(rect.Y, image.Height - 1));      int width = Math.Min(rect.Width, image.Width - x);      int height = Math.Min(rect.Height, image.Height - y);
      returnnew Rectangle(x, y, width, height);
  }// 裁剪图片static Bitmap CropImage(Bitmap source, Rectangle cropArea)
  {
      Bitmap target = new Bitmap(cropArea.Width, cropArea.Height);      using (Graphics g = Graphics.FromImage(target))
      {
          g.DrawImage(source, new Rectangle(0, 0, cropArea.Width, cropArea.Height),
              cropArea, GraphicsUnit.Pixel);
      }


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70048957/viewspace-3109181/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2026-01-07

  • 博文量
    108
  • 访问量
    102118