首页 > 其他分享 >模拟混合专家模型——滑块匹配领域应用学习

模拟混合专家模型——滑块匹配领域应用学习

时间:2024-12-27 12:26:38浏览次数:7  
标签:bg 匹配 val 滑块 list image cv2 tp 模拟

        混合专家模型(Mixture of Experts,简称MoE)是一种高效的神经网络架构,它将多个专业化的子模型(即“专家”)与一个门控网络相结合,以处理复杂任务。

        混合专家模型的核心思想是将一个大问题分解为多个小问题,每个小问题由一个在该领域有专业知识的专家模型来处理。通过这种方式,混合专家模型能够充分利用多个专家模型的专长,提高整体模型的性能。

        而对于混合专家模型来说,许多人比较陌生,其实可以认为这是一种较为通用的方法,适用于许多领域,比如自然语言处理、图像识别、语音识别、推荐系统等领域。

在这里,写者在图像识别中滑块匹配领域应用有所使用,效果良好。

未使用前87.2%准确率,使用后95.8%准确率,提升了约10%的准确率,错误率减少了约67.2%,对于大多数模型而言,基本上都已经到80-90%准确率,错误率减少才是最重要的。

使用前的算法(经过优化):

import cv2
import numpy as np
 
 
## 采用的是基础版本
def sliderSlip(address, width=50):
    """
    识别准确率为:0.872
    这里要说明一下,滑块可能与拼图的滑动长度不一致,要细微调整比例关系
    address:图片地址和名字
    width:从左边开始裁剪x轴宽度是多少
    list_class:边缘识别阈值
    list_d:边缘识别阈值下限
    list_h:边缘识别阈值上限
    list_val:保存每种阈值的最高匹配度
    list_tl_x:保存每种阈值的滑动距离
    return: X:移动X轴上的长度
    """
    # 读取图片,通过灰度加载来更好完成识别任务
    image = cv2.imread(address, cv2.IMREAD_GRAYSCALE)
 
    # 指定裁剪区域的起始位置和宽度、高度
    x, y = 0, 0  
    # 从左边开始裁剪x轴宽度是多少
    width = width
    # 获取图片的高
    height = image.shape[0]
 
    # 裁剪图像
    tp_image = image[y:y + height, x:x + width]  # 裁剪图片
    bg_image = image[y:y + height, width:image.shape[1]]  # 识别的背景图片
 
    # 高斯模糊
    tp_image = cv2.GaussianBlur(tp_image, (5, 5), sigmaX=0)
    bg_image = cv2.GaussianBlur(bg_image, (5, 5), sigmaX=0)
 
    # 灰度直方图均衡
    tp_image = cv2.equalizeHist(tp_image)
    bg_image = cv2.equalizeHist(bg_image)
 
    # 识别图片边缘
    # bg_edge = cv2.Canny(bg_image, 100, 200)
    # tp_edge = cv2.Canny(tp_image, 100, 200)
 
    # 匹配算法
    # res = cv2.matchTemplate(bg_edge, tp_edge, cv2.TM_CCOEFF_NORMED) #寻图
    # min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 寻找最优匹配
    # tl = max_loc  # 左上角点的坐标
    # X = tl[0]+width #x轴长度
 
    list_class = ["较高", "正常", "调试", "中", "低"]
    list_d = [150, 100, 10, 80, 10]
    list_h = [250, 200, 150, 150, 80]
    list_val = []
    list_tl_x = []
 
    # 所有分辨匹配机制
    for i in range(len(list_class)):
        bg_edge = cv2.Canny(bg_image, list_d[i], list_h[i])
        tp_edge = cv2.Canny(tp_image, list_d[i], list_h[i])
        res = cv2.matchTemplate(bg_edge, tp_edge, cv2.TM_CCOEFF_NORMED)  # 寻图
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 寻找最优匹配
        list_val.append(max_val)
        tl = max_loc  # 左上角点的坐标
        list_tl_x.append(tl[0])
    # 去除匹配为1.0
    n = 0
    for i in list_val:
        if i == 1.0:
            list_val[n] = 0
        n += 1
    # 获取最大匹配度的索引
    index = list_val.index(max(list_val))
    X = list_tl_x[index] + width  # x轴长度
    if list_val[index] < 0.2:
        # 最佳匹配度过低,采用众数匹配
        list_l = np.arange(10, 500, 50)
        list_u = np.arange(10, 500, 50)
        v = []
        x = []
        for i in list_l:
            for k in list_u:
                bg_edge = cv2.Canny(bg_image, i, k)
                tp_edge = cv2.Canny(tp_image, i, k)
                res = cv2.matchTemplate(bg_edge, tp_edge, cv2.TM_CCOEFF_NORMED)  # 寻图
                min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 寻找最优匹配
                v.append(max_val)
                x.append(max_loc[0])
        n = 0
        for i in v:
            if i == 1.0:
                v[n] = 0
            n += 1
        word_dict = {}
        n = 0
        for word in x:
            # 去除不匹配
            if word > 10:
                if word not in word_dict:
                    word_dict[word] = v[n]
                else:
                    word_dict[word] += v[n]
            n += 1
        # 修改滑动距离
        X = max(word_dict, key=word_dict.get) + width
    # 返回长度
    return X

而这里引入专家,滑块识别中就是算子可以作为专家,每个算子专家会有自己的特长,将他们提供的正确答案汇总,则会提高正确答案准确率。

Roberts算子
优点:
定位精度高,尤其在检测垂直边缘时表现优异。
缺点:
对噪声敏感,容易在噪声较多的图像中产生虚假边缘。
边缘检测结果可能较粗,不够精细。

Prewitt算子
优点:
实现简单,计算效率高。
对噪声有一定的抑制能力。
缺点:
边缘定位精度相对较低,可能产生边缘模糊。
对于细节丰富的图像,可能忽略一些细小的边缘信息。

Sobel算子
优点:
对噪声有较好的平滑作用,能够减少噪声对边缘检测的影响。
提供边缘方向信息,有助于后续的边缘处理。
缺点:
检测出的边缘可能出现多像素宽度,影响边缘的精确性。
对于复杂纹理的图像,边缘检测效果可能不理想。

Laplacian算子
优点:
各方向同性,能够检测任意方向的边缘。
二阶微分增强了边缘定位能力,锐化效果更好。
缺点:
对噪声非常敏感,容易在噪声区域产生虚假边缘。
单独使用时,可能无法准确区分边缘和噪声。

模拟专家模型算法如下:

## 采用的是专家模型
def sliderSlipHigh(address, width=50):
    """
    识别准确率为:0.9583
    这里要说明一下,滑块可能与拼图的滑动长度不一致,要细微调整比例关系
    address:图片地址和名字
    width:从左边开始裁剪x轴宽度是多少
    list_class:边缘识别阈值
    list_d:边缘识别阈值下限
    list_h:边缘识别阈值上限
    list_val:保存每种阈值的最高匹配度
    list_tl_x:保存每种阈值的滑动距离
    return: X:移动X轴上的长度
    """
 
    # Roberts算子
    def Roberts(image):
        kernelx = np.array([[-1, 0], [0, 1]], dtype=int)
        kernely = np.array([[0, -1], [1, 0]], dtype=int)
        x = cv2.filter2D(image, cv2.CV_16S, kernelx)
        y = cv2.filter2D(image, cv2.CV_16S, kernely)
        absX = cv2.convertScaleAbs(x)
        absY = cv2.convertScaleAbs(y)
        image = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
        return image
 
    # Prewitt 算子
    def Prewitt(image):
        kernelx = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=int)
        kernely = np.array([[-1, -1, -1], [0, 0, 0], [1, 1, 1]], dtype=int)
        x = cv2.filter2D(image, cv2.CV_16S, kernelx)
        y = cv2.filter2D(image, cv2.CV_16S, kernely)
        absX = cv2.convertScaleAbs(x)
        absY = cv2.convertScaleAbs(y)
        image = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
        return image
 
    # Sobel 算子
    def Sobel(image):
        x = cv2.Sobel(image, cv2.CV_16S, 1, 0)
        y = cv2.Sobel(image, cv2.CV_16S, 0, 1)
        absX = cv2.convertScaleAbs(x)
        absY = cv2.convertScaleAbs(y)
        image = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
        return image
 
    # 拉普拉斯算法
    def Laplacian(image):
        dst = cv2.Laplacian(image, cv2.CV_16S, ksize=3)
        image = cv2.convertScaleAbs(dst)
        return image
 
    # Roberts算子
    # kernelx = np.array([[-1, 0], [0, 1]], dtype=int)
    # kernely = np.array([[0, -1], [1, 0]], dtype=int)
 
    # Prewitt 算子
    # kernelx = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=int)
    # kernely = np.array([[-1, -1, -1], [0, 0, 0], [1, 1, 1]], dtype=int)
 
    # x = cv2.filter2D(image, cv2.CV_16S, kernelx)
    # y = cv2.filter2D(image, cv2.CV_16S, kernely)
 
    # # Sobel 算子
    # x = cv2.Sobel(image, cv2.CV_16S, 1, 0)
    # y = cv2.Sobel(image, cv2.CV_16S, 0, 1)
    #
    #
    # 转uint8
    # absX = cv2.convertScaleAbs(x)
    # absY = cv2.convertScaleAbs(y)
    # image = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
 
    # # 拉普拉斯算法
    # dst = cv2.Laplacian(image, cv2.CV_16S, ksize=3)
    # image = cv2.convertScaleAbs(dst)
 
    # 图片预处理
    def imageDeal(image,width):
        # 指定裁剪区域的起始位置和宽度、高度
        x = 0  
        y = 0
        width = width  # 从左边开始裁剪x轴宽度是多少
        height = image.shape[0]
 
        # 裁剪图像
        tp_image = image[y:y + height, x:x + width]
        bg_image = image[y:y + height, width:image.shape[1]]
 
        # 高斯模糊
        tp_image = cv2.GaussianBlur(tp_image, (5, 5), sigmaX=0)
        bg_image = cv2.GaussianBlur(bg_image, (5, 5), sigmaX=0)
 
        # 灰度直方图均衡
        tp_image = cv2.equalizeHist(tp_image)
        bg_image = cv2.equalizeHist(bg_image)
        return tp_image, bg_image
 
    # 识别图片边缘
    # bg_edge = cv2.Canny(bg_image, 100, 200)
    # tp_edge = cv2.Canny(c_image, 100, 200)
 
    # 匹配算法
    # res = cv2.matchTemplate(bg_edge, tp_edge, cv2.TM_CCOEFF_NORMED)
    # min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 寻找最优匹配
    # tl = max_loc  # 左上角点的坐标
    # print("匹配率:",max_val)
    # X= tl[0]+width
    # print(X)
 
    list_val = []  # 匹配值
    list_tl_x = []  # 匹配坐标
 
    # 循环处理将图片进行匹配处理
    def matchTemplate(bg_image, tp_image):
        list_l = np.arange(10, 400, 50)
        #list_l = np.arange(10, 200, 20) #更高精确度,但是时间更多一些
        list_u = np.arange(10, 400, 50)
        list_repeat = []
        for i in list_l:
            list_repeat.append(i)
            for k in list_u:
                if k not in list_repeat :
                    bg_edge = cv2.Canny(bg_image, i, k)
                    tp_edge = cv2.Canny(tp_image, i, k)
                    res = cv2.matchTemplate(bg_edge, tp_edge, cv2.TM_CCOEFF_NORMED)  # 寻图
                    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 寻找最优匹配
                    list_val.append(max_val)
                    tl = max_loc  # 左上角点的坐标
                    list_tl_x.append(tl[0])
 
    # 通过不同算子的处理
    image = cv2.imread(address, cv2.IMREAD_GRAYSCALE)
 
    b, t = imageDeal(Roberts(image),width)
    matchTemplate(b, t)
 
    b, t = imageDeal(Prewitt(image),width)
    matchTemplate(b, t)
 
    b, t = imageDeal(Sobel(image),width)
    matchTemplate(b, t)
 
    b, t = imageDeal(Laplacian(image),width)
    matchTemplate(b, t)
 
    # 普通边缘识别
    b, t = imageDeal(image,width)
    matchTemplate(b, t)
 
    # 显示裁剪后的图像
    n = 0
    for i in list_val:
        if i == 1.0:
            list_val[n] = 0
        n += 1
    word_dict = {}
    n = 0
 
    # 去除坐标异常的数据
    for word in list_tl_x:
        if word > 10 and word < image.shape[1] - width* 2 - 10:
            if word not in word_dict:
                word_dict[word] = list_val[n]
            else:
                word_dict[word] += list_val[n]
        n += 1
 
    # 排序
    list_d = sorted(word_dict.items(), key=lambda d: d[1], reverse=True)
    list_keys = []
    for i in list_d:
        list_keys.append(i[0])
 
    # 使用集合来跟踪已考虑的元素
    seen = set()
    val_dict = {}
 
    n = 3  # 聚类距离
 
    # 寻找相似距离
    def seen_find(number):
        for i in seen:
            if i - n <= number <= i + n:
                return i
 
    # 聚类合并
    for i in list_keys:
        change = 0
        # 检查当前元素是否在允许的范围内
        if not any(abs(i - k) <= n and k != i for k in seen):
            change = 1
            seen.add(i)
            if i not in val_dict:
                val_dict[i] = word_dict.pop(i)
        if change == 0:  # 当没有改变值的时候说明没有通过判断语句,所以是合并的值,将值放入
            # 通过找到相似key来传递value
            val_dict[seen_find(i)] += word_dict.pop(i)
 
    # 拿取最大权重对应的距离
    X = max(val_dict, key=val_dict.get) + width
    # 返回长度
    return X

其他领域思想参考:

对于图像识别多分类问题,可以训练识别几种分类作为一种专家,然后将几个专家协调起来,通过它们对图像的匹配度打分,或者是对图像多标签标记(颜色专家、形状专家)这样能实现小模型就能训练出特别好的效果。

标签:bg,匹配,val,滑块,list,image,cv2,tp,模拟
From: https://blog.csdn.net/weixin_52810349/article/details/144764610

相关文章

  • 三维球体空间中光线反射模拟与三维点云提取matlab仿真
    1.程序功能描述三维球体空间中光线反射模拟与三维点云提取matlab仿真。设置一个三维的椭球模型,作为墙壁,然后根据光线的反射原理,设计三维空间内,光线的反射效果。在三维系统中,光线反射本质是是曲面上每个点对应的切面的反射处理。每个反射点作为空间三维点云的坐标点,进行三维......
  • 如何提前预测足球冷门比赛?从机构走势和模型模拟的分歧点入手
    我们知道,足球是圆的,足球比赛是一项复杂的团队运动,有很多的不确定性,容易产生一些让人大跌眼镜的“冷门”,比如卡塔尔世界杯冠军阿根廷的首战居然被沙特逆转了,这也是足球的魅力所在。但这种冷门比赛毕竟是低概率事件,在赛前是否有迹可循呢?当然,基本面因素决定了体育竞技实力,球队内......
  • 字符串匹配:BF算法 | KMP算法 | Z函数
    什么是字符串匹配?给你一个字符串str,问你这个字符串中是否包含字符串sub。例如:str="abcdef",sub="cdef",问str中是不是有sub。一.BF算法BF算法(BruteForce),翻译成中文就是暴力匹配算法。暴力匹配其实很好想,不就让我们判断str中有没有sub嘛,直接一个一个来。定义两个指针,一个指st......
  • SliderRange 双滑块范围选择器
    SliderRange双滑块范围选择器一个轻量级但功能强大的双滑块范围选择器组件,完美适配移动端和PC端,为您的项目提供直观的范围选择体验。......
  • 蓝桥杯青少组python编程模拟题
    1、以123为随机种子,随机生成10个介于到999(含)之间的随机数,每个随1(含)机数后跟随一个逗号进行分隔,屏幕输出这10个随机数。  2、请实现以下功能:随机选择手机品牌列表brandlist=’华为’,苹果’,‘诺基亚‘,‘OPPO’,‘小米’中的一个手机品牌,屏幕输出。  3、获得用户......
  • 12.26 CW 模拟赛 T1. 平均
    思路首先你发现假设当前的平均数是\(a\),其中\(\lceila\rceil=k\),那么你势必要选上所有\(<k\)的数来拉低平均数,然后贪心的从小到大选\(\geqk\)的数来提高贡献如果想不到也可以这样想,对于一个确定的平均数,一定要尽可能的让比平均数小的数更多,才能更多的......
  • CW 12.26 模拟赛 赛时记录
    前言虽然说有点难受,但是还是好好考考试只需要管考试相关的即可,别想太多冷静,就这样看题先过一遍吧,看看感觉怎么样,今天时间要短一点,不开心\(\rm{T1}\)至少题意清楚,不管了\(\rm{T2}\)这么有实力,很像\(\rm{Indec\Sequence}\)\(\rm{T3}\)多半要观察性质......
  • Jmeter自学【8】- 使用JMeter模拟设备通过MQTT发送数据
    今天使用jmeter推送数据到MQTT,给大家分享一下操作流程。一、安装JMeter参考文档:Jmeter自学【1】-Jmeter安装、配置二、安装MQTT插件1、下载插件我的Jmeter版本是5.6.3,用到的插件是:mqtt-xmeter-2.0.2-jar-with-dependencies.jar下载链接:https://pan.baidu.com/s/1mWgvSkX......
  • STM32-I2C软件模拟
    1.I2C介绍I2C是一种多主机、两线制、低速串行通信总线,广泛用于微控制器和各种外围设备之间的通信。它使用两条线路:串行数据线(SDA)和串行时钟线(SCL)进行双向传输。2.时序启动条件:SCL高电平时、SDA由高电平变为低电平停止条件:SCL高电平时、SDA由低电平变为高电平除此之外,不允许......
  • 请使用es5模拟实现一个es6的symbol
    在ES5中,没有原生的Symbol类型,但我们可以尝试通过创建一个具有唯一标识符的对象来模拟Symbol的行为。请注意,这种模拟并不完全等同于ES6的Symbol,但它可以提供类似的功能。以下是一个简单的模拟实现:(function(){varsymbolRegistry={};varsymbolCounter=0;fu......