基于.NET后端实现图片搜索图片库 核心是计算上传图片与库中图片的特征向量相似度并排序展示结果

基于.NET 后端实现图片搜索图片库的方案,核心是计算上传图片与库中图片的特征向量相似度并排序展示结果。

整体思路

  1. 图像特征提取:使用深度学习模型(如 ResNet)提取图片的特征向量。
  2. 特征向量存储:将图片的特征向量存储在数据库中。
  3. 相似度计算:使用余弦相似度算法计算上传图片与库中图片的特征向量相似度。
  4. 结果排序与展示:按相似度从高到低排序,并将相似图像展示给用户。

实现步骤

1. 项目搭建

创建一个新的 .NET Web API 项目,安装必要的 NuGet 包:

  • Microsoft.EntityFrameworkCore.SqlServer:用于与 SQL Server 数据库交互。
  • ML.NET:用于特征提取和相似度计算。
  • ImageSharp:用于图像处理。
2. 图像特征提取

使用 ResNet 模型提取图片的特征向量。以下是一个示例代码:

cs 复制代码
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using Microsoft.ML;
using Microsoft.ML.Data;
using Microsoft.ML.Vision;

public class ImageData
{
    [LoadColumn(0)]
    public string ImagePath;
}

public class ImagePrediction
{
    [ColumnName("Score")]
    public float[] Score;
}

public class FeatureExtractor
{
    private readonly MLContext _mlContext;
    private readonly ITransformer _model;

    public FeatureExtractor()
    {
        _mlContext = new MLContext();
        var data = _mlContext.Data.LoadFromEnumerable(new List<ImageData>());
        var pipeline = _mlContext.Transforms.LoadImages(outputColumnName: "input", imageFolder: "", inputColumnName: nameof(ImageData.ImagePath))
            .Append(_mlContext.Transforms.ResizeImages(outputColumnName: "input", imageWidth: 224, imageHeight: 224, inputColumnName: "input"))
            .Append(_mlContext.Transforms.ExtractPixels(outputColumnName: "input"))
            .Append(_mlContext.Model.LoadTensorFlowModel("resnet50.pb")
                .ScoreTensorFlowModel(outputColumnNames: new[] { "output" }, inputColumnNames: new[] { "input" }, addBatchDimensionInput: true));

        _model = pipeline.Fit(data);
    }

    public float[] ExtractFeatures(string imagePath)
    {
        var imageData = new ImageData { ImagePath = imagePath };
        var predictionEngine = _mlContext.Model.CreatePredictionEngine<ImageData, ImagePrediction>(_model);
        var prediction = predictionEngine.Predict(imageData);
        return prediction.Score;
    }
}
3. 数据库设计与存储

创建一个 SQL Server 数据库,包含一个表用于存储图片的路径和特征向量。以下是一个示例表结构:

sql 复制代码
CREATE TABLE Images (
    Id INT PRIMARY KEY IDENTITY(1,1),
    ImagePath NVARCHAR(255) NOT NULL,
    FeatureVector NVARCHAR(MAX) NOT NULL
);

使用 Entity Framework Core 进行数据库操作:

cs 复制代码
using Microsoft.EntityFrameworkCore;

public class ImageDbContext : DbContext
{
    public DbSet<ImageEntity> Images { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("YourConnectionString");
    }
}

public class ImageEntity
{
    public int Id { get; set; }
    public string ImagePath { get; set; }
    public string FeatureVector { get; set; }
}
4. 相似度计算

使用余弦相似度算法计算两个特征向量的相似度:

cs 复制代码
public static double CosineSimilarity(float[] vectorA, float[] vectorB)
{
    double dotProduct = 0;
    double normA = 0;
    double normB = 0;

    for (int i = 0; i < vectorA.Length; i++)
    {
        dotProduct += vectorA[i] * vectorB[i];
        normA += Math.Pow(vectorA[i], 2);
        normB += Math.Pow(vectorB[i], 2);
    }

    normA = Math.Sqrt(normA);
    normB = Math.Sqrt(normB);

    if (normA == 0 || normB == 0)
    {
        return 0;
    }

    return dotProduct / (normA * normB);
}
5. 图片搜索 API

创建一个 Web API 接口,用于接收上传的图片并返回相似图片列表:

cs 复制代码
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;

[ApiController]
[Route("[controller]")]
public class ImageSearchController : ControllerBase
{
    private readonly ImageDbContext _dbContext;
    private readonly FeatureExtractor _featureExtractor;

    public ImageSearchController(ImageDbContext dbContext, FeatureExtractor featureExtractor)
    {
        _dbContext = dbContext;
        _featureExtractor = featureExtractor;
    }

    [HttpPost]
    public IActionResult Search([FromForm] IFormFile image)
    {
        // 保存上传的图片
        var uploadPath = "uploads/" + image.FileName;
        using (var stream = new FileStream(uploadPath, FileMode.Create))
        {
            image.CopyTo(stream);
        }

        // 提取上传图片的特征向量
        var uploadFeatures = _featureExtractor.ExtractFeatures(uploadPath);

        // 从数据库中获取所有图片的特征向量
        var allImages = _dbContext.Images.ToList();

        // 计算相似度并排序
        var similarities = new List<(ImageEntity Image, double Similarity)>();
        foreach (var imageEntity in allImages)
        {
            var features = imageEntity.FeatureVector.Split(',').Select(float.Parse).ToArray();
            var similarity = CosineSimilarity(uploadFeatures, features);
            similarities.Add((imageEntity, similarity));
        }

        similarities = similarities.OrderByDescending(s => s.Similarity).ToList();

        // 返回相似图片列表
        var result = similarities.Select(s => s.Image.ImagePath).ToList();
        return Ok(result);
    }
}

总结

通过以上步骤,你可以实现一个基于 .NET 后端的图片搜索图片库功能。用户上传图片后,系统会提取其特征向量,计算与库中图片的相似度,并按相似度从高到低排序展示相似图片。

相关推荐
孜然卷k3 分钟前
C#项目 在Vue/React前端项目中 使用使用wkeWebBrowser引用并且内部使用iframe网页外链 页面部分白屏
前端·vue.js·react.js·c#
专注VB编程开发20年1 小时前
C# VB.NET多进程-管道通信,命名管道(Named Pipes)
开发语言·c#·.net
百锦再1 小时前
Rider 全面解析:跨平台 .NET IDE 的核心技术与高效实践指南
linux·ide·.net·sdk·core·rider
mit6.8241 小时前
[Subtitle Edit] 字幕格式处理 | .Net依赖管理(NuGet)
.net
唐青枫3 小时前
C#.NET 泛型详解
c#·.net
阿蒙Amon3 小时前
C#日期、时间和时区:全球化应用的时间处理艺术
java·服务器·c#
学不动CV了3 小时前
深入理解C语言内存空间、函数指针(三)(重点是函数指针)
c语言·arm开发·数据库·stm32·单片机·嵌入式硬件·c#
wangnaisheng11 小时前
【C#】GraphicsPath的用法
c#·gdi
天上游戏地下人间12 小时前
基于Opencv的缺陷检测实战
图像处理·人工智能·计算机视觉