OHIF Viewers 项目介绍

news2024/11/15 7:10:07

项目结构

项目架构

│
├── extensions
│   ├── default               # 默认功能
│   ├── cornerstone           # 使用 Cornerstonejs 处理 2D/3D 图像
│   ├── cornerstone-dicom-sr  # 结构化报告 (DICOM SR)
│   ├── measurement-tracking  # 测量追踪功能
│   └── dicom-pdf             # 在视口中查看 DICOM 包装的 PDF 文件
│   # 还有更多扩展功能...
│
├── modes
│   └── longitudinal          # 纵向测量追踪模式
│   └── basic-dev-mode        # 使用 Cornerstone 的基础查看器 (面向开发者的模式)
│   # 还有更多模式...
│
├── platform
│   ├── core                  # 业务逻辑核心
│   ├── i18n                  # 国际化支持
│   ├── ui                    # React 组件库
│   └── app                   # 连接平台和扩展项目
│
├── ...                      # 其他共享配置文件
├── lerna.json               # MonoRepo (Lerna) 设置
├── package.json             # 共享的开发依赖项和命令
└── README.md                # 项目说明文档

OHIF v3 由以下组件组成,将在进一步中详细描述 部分:

  • @ohif/app:控制扩展注册、模式的核心框架 组合和路由。
  • @ohif/core:一个有用且可重复使用的医学成像功能库 对于网络。
  • @ohif/ui:一个可重用的组件库,用于构建 OHIF 风格的应用程序 跟。
  • Extensions:一组用于构建应用程序的构建块。OHIF组织 维护一些核心库。
  • Modes:告诉 @ohif/app 如何撰写的配置对象 扩展,用于在平台的不同路线上构建应用程序。

OHIF 为一些常见的使用场景维护了少量功能强大的扩展。这些扩展与 OHIF/Viewers 仓库一起存放在项目的根目录下的 extensions/ 文件夹中。

下面那个表格展示了 OHIF 中各种类型模块的功能描述。

OHIF V3 组件库

@ohif/app​

此库是使用模式、扩展和构建的核心库 一个应用程序。扩展可以作为应用配置传入,并且将 应用程序在适当的时间使用和初始化。后 初始化 Viewer 将使用扩展和模式并构建 所需的路线,然后可以通过研究列表访问这些内容,或直接通过 URL 参数。

发布时,模式也将通过配置插入到应用程序中,但这 仍然是一个正在开发/讨论的领域,他们目前正在 在测试版中从窗户拉出。

这个框架的未来想法只涉及添加模式和获取 在运行时或构建时都需要扩展版本,但此决定 还有待商榷。

视口重新渲染优化

我们利用 React 记忆模式来防止不必要的重新渲染 除非视口属性的某些方面发生变化。你可以采取 查看组件中的函数以 看看这是如何完成的。areEqualOHIFCornerstoneViewport

function areEqual(prevProps, nextProps) {  
if (prevProps.displaySets.length !== nextProps.displaySets.length) {   
 return false;  
}  
if (    prevProps.viewportOptions.orientation !==    nextProps.viewportOptions.orientation  ) 
{    return false;  }  // rest of the code

如您所见,我们检查道具是否为真,如果是,我们将 如果属性或方向发生变化,请重新渲染视口 变化。needsRerenderingdisplaySets

我们使用 viewportId 来标识视口,并在 React 中将其用作键 渲染。这很重要,因为它允许我们跟踪视口 以及它的状态,并且还让 React 在 网格而不重新渲染它。但是,在某些情况下,我们需要这样做 强制重新渲染视口,例如,当视口被冻结时 具有新的细分。对于这些情况,我们使用 prop 强制重新渲染视口。您可以将其添加到needsRerenderingviewportOptions

视口组件由组件管理。哪个视口 组件的使用取决于:ViewportGrid

  • 挂起协议
  • 布局配置
  • 已注册的 SopClassHandlers

@ohif/core​

OHIF核心是一套经过精心维护和测试的基于网络的医学成像设备 函数和类。此库包括用于以下位置的管理器和服务 在查看器应用程序中。

OHIF 核心在很大程度上类似于 v2 中的 @ohif/core 库,但是很多 逻辑已移至扩展:但是,有关 DICOMWeb 和其他的所有逻辑 数据获取机制已被拉出,因为这些机制现在存在于扩展中, 稍后再述。

@ohif/ui​

首先,我们发现一个巨大的时间消耗/进入壁垒正在建造新的 UI及时符合OHIF的主题。出于这个原因,我们建立了一个新的 UI组件库,其中包含构建其所需的所有组件 自己的观众。

这些组件仅是演示性的,因此您可以将它们与任何内容重复使用 你想要的逻辑。由于组件是演示性的,因此您可以换掉 如果您希望为白标,请使用具有符合 API 的自定义 UI 库的 @ohif/ui 观众。UI 库是为了让开发更轻松、更快捷,但 扩展组件不是强制性的。

OHIF V3体系结构

Video Tutorials | OHIF 扩展模式

OHIF CLI 促进了创建、链接和发布 OHIF 模式和扩展。以下视频演示了如何使用 CLI 进行

  • 创建模式和扩展
  • 链接本地模式和扩展
  • NPM 的发布模式和扩展
  • 向 OHIF 添加已发布的模式和扩展
  • 向 OHIF 提交模式

更新数据源的配置

可以使用该方法更新现有数据源的配置。以下代码片段 代码演示了如何使用来更新 配置现有 DICOMWeb 数据源(名为 ),并使用 Google Cloud Healthcare API 数据源的配置。ExtensionManager.updateDataSourceConfigurationupdateDataSourceConfigurationdicomweb

extensionManager.updateDataSourceConfiguration( "dicomweb",  {    name: 'GCP',    wadoUriRoot:      'https://healthcare.googleapis.com/v1/projects/ohif-cloud-healthcare/locations/us-east4/datasets/ohif-qa-dataset/dicomStores/ohif-qa-2/dicomWeb',    qidoRoot:      'https://healthcare.googleapis.com/v1/projects/ohif-cloud-healthcare/locations/us-east4/datasets/ohif-qa-dataset/dicomStores/ohif-qa-2/dicomWeb',    wadoRoot:      'https://healthcare.googleapis.com/v1/projects/ohif-cloud-healthcare/locations/us-east4/datasets/ohif-qa-dataset/dicomStores/ohif-qa-2/dicomWeb',    qidoSupportsIncludeField: true,    imageRendering: 'wadors',    thumbnailRendering: 'wadors',    enableStudyLazyLoad: true,    supportsFuzzyMatching: true,    supportsWildcard: false,    dicomUploadEnabled: true,    omitQuotationForMultipartRequest: true,  },);

模板:布局模式

概述

LayoutTemplates是 v3 中的一个新概念,模式使用它来控制布局 的路线。布局模板是一个 React 组件,它被赋予了一组 定义 API 以访问工具栏状态、命令和热键的管理器,如 以及布局模板定义的属性。

例如,默认的 LayoutTemplate 接受 leftPanels、rightPanels 和 视口作为属性,它使用它来构建其视图。

此外,对结构具有完全的控制权。 应用。你可以在左侧放置工具,或者有严格的指导 工作流 通过以编程方式设置工具,您可以选择适合您的用例。layout template

const getLayoutTemplateModule = (/* ... */) => [
  {
    id: 'exampleLayout',
    name: 'exampleLayout',
    component: ExampleLayoutComponent,
  },
];

传递给的是经理和服务 使用定义的模式左/右面板、模式定义的视口和 OHIF 。LayoutTemplate 利用 extensionManager 来抓取类型 扩展模块条目:propslayoutTemplateViewportGridComp*.getModuleEntry(id)

布局模板的简化代码为:Default extension

extensions/default/src/ViewerLayout/index.jsx

import React from 'react';
import { SidePanel } from '@ohif/ui';

function Toolbar({ servicesManager }) {
  const { ToolBarService } = servicesManager.services;

  return (
    <>
      // ToolBarService.getButtonSection('primary') to get toolbarButtons
      {toolbarButtons.map((toolDef, index) => {
        const { id, Component, componentProps } = toolDef;
        return (
          <Component
            key={id}
            id={id}
            {...componentProps}
            bState={buttonState}
            isActive={isActive}
            onInteraction={args => ToolBarService.recordInteraction(args)}
          />
        );
      })}
    </>
  );
}

function ViewerLayout({
  // From Extension Module Params
  extensionManager,
  servicesManager,
  hotkeysManager,
  commandsManager,
  // From Modes
  leftPanels,
  rightPanels,
  viewports,
  ViewportGridComp,
}) {
  const getPanelData = id => {
    const entry = extensionManager.getModuleEntry(id);
    const content = entry.component;

    return {
      iconName: entry.iconName,
      iconLabel: entry.iconLabel,
      label: entry.label,
      name: entry.name,
      content,
    };
  };

  const getViewportComponentData = viewportComponent => {
    const entry = extensionManager.getModuleEntry(viewportComponent.namespace);

    return {
      component: entry.component,
      displaySetsToDisplay: viewportComponent.displaySetsToDisplay,
    };
  };

  const leftPanelComponents = leftPanels.map(getPanelData);
  const rightPanelComponents = rightPanels.map(getPanelData);
  const viewportComponents = viewports.map(getViewportComponentData);

  return (
    <div>
      <Toolbar servicesManager={servicesManager} />

      <div>
        {/* LEFT SIDEPANELS */}
        <SidePanel
          side="left"
          defaultComponentOpen={leftPanelComponents[0].name}
          childComponents={leftPanelComponents}
        />

        {/* TOOLBAR + GRID */}
        <ViewportGridComp
          servicesManager={servicesManager}
          viewportComponents={viewportComponents}
          commandsManager={commandsManager}
        />

        {/* Right SIDEPANELS */}
        <SidePanel
          side="right"
          defaultComponentOpen={rightPanelComponents[0].name}
          childComponents={rightPanelComponents}
        />
      </div>
    </div>
  );
}

悬挂协议

悬挂协议是任何放射学观察器的重要组成部分。 OHIF 使用悬挂协议来处理视口中图像的排列。在 简而言之,已注册的协议将与 DisplaySet 匹配 可用。每个协议都会得到一个分数,并且它们会被排名。这 应用获胜协议(最高分)并运行其设置以用于视口 待安排。

在挂起协议中,您可以:OHIF-v3

  • 定义视口应从什么布局开始(例如,2x2 布局)
  • 指定视口的类型及其方向(例如,堆栈、带有 Sagittal 视图的体积)
  • 定义在布局的哪个视口中显示哪个 displaySets(例如,具有“CT”模态的 displaySet 和 “Coronary Arteries” 的 “SeriesDescription” 将显示在布局的第一个视口中)
  • 应用某些初始视口设置(例如,反转对比度、跳转到特定切片等)
  • 为视口添加特定的同步规则(例如,同步索引 1、2 的视口缩放,或同步索引 2、3 的视口的 VOI)

使用您可以提供/注册 OHIF 的协议以 利用。hangingProtocolModule

这是一个示例协议,如果使用该协议,它将悬挂一个 1x3 布局,第一个视口显示 CT 图像,第二个视口显示 PT 图像,第三个视口显示它们的融合,所有这些都以矢状方向实现视图

const oneByThreeProtocol = {
  id: 'oneByThreeProtocol',
  locked: true,
  name: 'Default',
  createdDate: '2021-02-23T19:22:08.894Z',
  modifiedDate: '2022-10-04T19:22:08.894Z',
  availableTo: {},
  editableBy: {},
  imageLoadStrategy: 'interleaveTopToBottom',
  protocolMatchingRules: [
    {
      attribute: 'ModalitiesInStudy',
      constraint: {
        contains: ['CT', 'PT'],
      },
    },
  ],
  displaySetSelectors: {
    ctDisplaySet: {
      seriesMatchingRules: [
        {
          weight: 1,
          attribute: 'Modality',
          constraint: {
            equals: {
              value: 'CT',
            },
          },
          required: true,
        },
        {
          weight: 1,
          attribute: 'isReconstructable',
          constraint: {
            equals: {
              value: true,
            },
          },
          required: true,
        },
      ],
    },
    ptDisplaySet: {
      seriesMatchingRules: [
        {
          attribute: 'Modality',
          constraint: {
            equals: 'PT',
          },
          required: true,
        },
        {
          weight: 1,
          attribute: 'isReconstructable',
          constraint: {
            equals: {
              value: true,
            },
          },
          required: true,
        },
        {
          attribute: 'SeriesDescription',
          constraint: {
            contains: 'Corrected',
          },
        },
      ],
    },
  },
  stages: [
    {
      id: 'hYbmMy3b7pz7GLiaT',
      name: 'default',
      viewportStructure: {
        layoutType: 'grid',
        properties: {
          rows: 1,
          columns: 3,
        },
      },
      viewports: [
        {
          viewportOptions: {
            viewportId: 'ctAXIAL',
            viewportType: 'volume',
            orientation: 'sagittal',
            initialImageOptions: {
              preset: 'middle',
            },
            syncGroups: [
              {
                type: 'voi',
                id: 'ctWLSync',
                source: true,
                target: true,
              },
            ],
          },
          displaySets: [
            {
              id: 'ctDisplaySet',
            },
          ],
        },
        {
          viewportOptions: {
            viewportId: 'ptAXIAL',
            viewportType: 'volume',
            orientation: 'sagittal',
            initialImageOptions: {
              preset: 'middle',
            },
          },
          displaySets: [
            {
              id: 'ptDisplaySet',
            },
          ],
        },
        {
          viewportOptions: {
            viewportId: 'fusionSAGITTAL',
            viewportType: 'volume',
            orientation: 'sagittal',
            initialImageOptions: {
              preset: 'middle',
            },
            syncGroups: [
              {
                type: 'voi',
                id: 'ctWLSync',
                source: false,
                target: true,
              },
            ],
          },
          displaySets: [
            {
              id: 'ctDisplaySet',
            },
            {
              options: {
                colormap: 'hsv',
                voi: {
                  windowWidth: 5,
                  windowCenter: 2.5,
                },
              },
              id: 'ptDisplaySet',
            },
          ],
        },
      ],
      createdDate: '2021-02-23T18:32:42.850Z',
    },
  ],
  numberOfPriorsReferenced: -1,
};


function getHangingProtocolModule() {
  return [
    {
      id: 'oneByThreeProtocol',
      protocol: oneByThreeProtocol,
    },
  ];
}

协议

id

协议的唯一标识符,此 ID 可以在模式配置中使用 指定应为特定模式使用哪个协议。一种模式可以 通过其 ID 请求协议(这使得 OHIF 在没有的情况下应用该协议 matching),或者提供一个 ID 数组,该数组将 使 ProtocolEngine 选择最佳匹配协议(基于 protocolMatching rules,这是下一节)。

imageLoadStrategy

图像加载策略指定了一个函数(按名称),其中包含要重新排序的逻辑 图像加载请求。这允许加载之前查看的图像 比装得更晚的早。可用的策略包括:

  • interleaveTopToBottom 从顶部开始,然后向底部工作,用于正在加载的所有序列
  • interleaveCenter 就像从上到下一样,但从中心开始
  • 第 n 个实例是加载每 n 个实例的策略,从中心开始 和终点,然后沿着图像逐渐填充。这导致部分 图像查看非常快。
protocolMatchingRules

协议的标准列表以及提供的排名分数。

  • weight:匹配规则的权重。最终,所有注册的 协议根据权重进行排序,获胜的协议获得 应用于查看器。
  • attribute:需要匹配的标签。这可以是 研究级元数据或自定义属性,例如“StudyInstanceUID”, “StudyDescription”, “ModalitiesInStudy”, “NumberOfStudyRelatedSeries”, “NumberOfSeriesRelatedInstances” 除了这些标签之外,您还可以使用之前注册的自定义属性。 我们稍后将对此进行详细了解。
  • from:表示属性的来源。这允许获取值 从其他对象(如实例对象)而不是从 当前的一个。prior
  • constraint:属性需要满足的约束。它接受的 a 可以是 [、、、、、validatorequalsdoesNotEqualcontainsdoesNotContainstartsWithendsWidth]
from 属性

该属性允许您从另一个对象中检索要测试的属性,例如上一个研究、研究的整个列表或模块中提供的其他值。from

OHIF 提供的值可供您使用:

  • activeStudy:使用活动研究的元数据进行匹配
  • studies:使用研究列表(所有研究)的元数据进行匹配
  • allDisplaySets:所有可用的显示集
  • displaySets:如果选择器与某个研究匹配,则这些是该研究的显示集
  • prior:研究列表中第一个研究的元数据,该研究不是活动研究
  • options:在匹配过程中,我们还提供了一个 Options 对象,其中包含您可以用作值的以下信息:from
  • studyInstanceUIDsIndex:研究列表中的研究索引
  • instance:被匹配实例的元数据,恰好是 displaySet.instance 元数据。
displaySetSelectors(必需)

定义协议将用于排列的显示集。

  displaySetSelectors: {
    ctDisplaySet: {
      seriesMatchingRules: [
        {
          weight: 1,
          attribute: 'Modality',
          constraint: {
            equals: {
              value: 'CT',
            },
          },
          required: true,
        },
        {
          weight: 1,
          attribute: 'isReconstructable',
          constraint: {
            equals: {
              value: true,
            },
          },
          required: true,
        },
      ],
    },
    ptDisplaySet: {
      seriesMatchingRules: [
        {
          attribute: 'Modality',
          constraint: {
            equals: 'PT',
          },
          required: true,
        },
        {
          weight: 1,
          attribute: 'isReconstructable',
          constraint: {
            equals: {
              value: true,
            },
          },
          required: true,
        },
        {
          attribute: 'SeriesDescription',
          constraint: {
            contains: 'Corrected',
          },
        },
      ],
    },
  }

如上所述,我们指定了两个 displayset:1) ctDisplaySet 、 2) ptDisplaySet ctDisplaySet 将与所有 CT 和可重构的系列匹配 ptDisplaySet 将与所有 PT 和可重构的系列匹配。

如您所见,每个选择器都由一个作为键和一组 (displaySetMatchingRules) 组成,后者为 displaySet 提供分数 根据匹配规则。得分最高的 displaySet 将用于 。idseriesMatchingRulesid

阶段

每个协议都可以定义一个或多个阶段。每个阶段都定义了特定的布局和视口规则。因此,该属性是一个对象数组,每个对象都是一个阶段。stages

viewportStructure(视口结构)

定义查看器的布局。您可以定义 和 的数量。应该有数量 属性中的视口配置。请注意,视口的顺序是首先是行,然后是列。rowscolumnsrows * columnsviewports

viewportStructure: {
    type: 'grid',
    properties: {
      rows: 1,
      columns: 2,
      viewportOptions: [],
    },
},

除了相等的视口大小外,您还可以定义视口以跨越多行或多列。

viewportStructure: {
    type: 'grid',
    properties: {
      rows: 1,
      columns: 2,
      viewportOptions: [
        {
          x: 0,
          y: 0,
          width: 1 / 4,
          height: 1,
        },
        {
          x: 1 / 4,
          y: 0,
          width: 3 / 4,
          height: 1,
        },
      ],
    },
},
视口

此字段包括将挂在查看器上的视口。

viewports: [
  {
    viewportOptions: {
      viewportId: 'ctAXIAL',
      viewportType: 'volume',
      orientation: 'sagittal',
      initialImageOptions: {
        preset: 'middle',
      },
      syncGroups: [
        {
          type: 'voi',
          id: 'ctWLSync',
          source: true,
          target: true,
        },
      ],
    },
    displaySets: [
      {
        id: 'ctDisplaySet',
      },
    ],
  },
  // the rest
],

服务

具体的可以查看ohif官方文档哦~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2085294.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

备战秋招60天算法挑战,Day28

题目链接&#xff1a; https://leetcode.cn/problems/climbing-stairs/ 视频题解&#xff1a; https://www.bilibili.com/video/BV1h1421t7W3/ LeetCode 70.爬楼梯 题目描述 假设你正在爬楼梯。需要n阶你才能到达楼顶。 每次你可以爬1或2个台阶。你有多少种不同的方法可以爬到…

Nacos2.4.0兼容达梦数据库

这段时间公司在搞国产化&#xff0c;发现当前的nacos版本只支持MySQL和derby数据库&#xff0c;后来翻看官方文档以后&#xff0c;官方文档说2.2以后支持达梦数据库了&#xff0c;但是需要插件。 按照他的思路再结合其他资料&#xff0c;我们开始搞起来&#xff01; 一、下载…

【SpringCloud应用框架】GateWay异步非阻塞模型

Spring Cloud Alibaba 之 GateWay工作流程GateWay搭建 文章目录 一、GateWay工作流程工作流程的核心点总结 二、GateWay搭建 一、GateWay工作流程 流程图如下&#xff1a; 核心概念&#xff1a; 客户端向 Spring Cloud Gateway 发出请求。如果Gateway Handler Mapping确定请…

2024年世界机器人大会精彩回顾-人形机器人的天下

8 月 25 日&#xff0c; 2024 世界机器人大会在北京北人亦创国际会展中心闭幕。本次大会以“共育新质生产力 共享智能新未来”为主题&#xff0c;同期举办论坛、博览会、大赛及配套活动&#xff0c;机器人创新新品、应用新场景纷纷亮相。 2024 世界机器人大会分为论坛、博览会、…

qml formLayout实现方式

一、背景 我们制作界面时&#xff0c;通常有表单界面需要制作&#xff0c;如下图&#xff1a; 但是Qt5 是没有 formLayout 的&#xff0c;直到Qt6才有&#xff0c;所以现在 qml 使用 TableView 来实现这个样式 二、实现 enum ComponentType {TitleText,Text,Button,Image} …

开放式耳机漏音有多大?解密最值得购买的五大品牌!

​现在的很多开放式耳机漏音情况已经得到很好的控制了&#xff0c;特别是大品牌的耳机。现在耳机市场上&#xff0c;开放式耳机因为外观时尚、戴着舒服&#xff0c;成了大家日常爱用的热门货。但是&#xff0c;市面上的开放式耳机品牌多得眼花缭乱&#xff0c;质量也是高低不一…

如何使用ssm实现基于JAVA的中小型企业财务管理

TOC ssm364基于JAVA的中小型企业财务管理jsp 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;…

debian12 - openssh-9.6.P1的编译安装(真机 - 联想G480)

文章目录 debian12 - openssh-9.6.P1的编译安装(真机 - 联想G480)概述笔记G480上安装debian12配置debian12现在用WindTerm_2.6.0按照telnet方式去连接试试配置debian12中的telnet安装telnet服务查看所有服务当前ssh, telnet状态准备更新openssl3.2和openssh在真机上更新openssl…

Andon安灯系统在汽车零部件工厂起到什么作用?

在当今竞争激烈的汽车市场中&#xff0c;汽车零部件工厂的高效运作和高质量生产至关重要。而 Andon 安灯系统作为一种先进的生产管理工具&#xff0c;在汽车零部件工厂中发挥着举足轻重的作用。 一、Andon安灯系统实时监控生产状态 汽车零部件工厂的生产线通常较为复杂&#x…

Quartz定时任务框架——若依

文章目录 定时任务的执行新增定时任务订单任务状态修改quartz的集群模式 定时任务的执行 新增定时任务 订单任务状态修改 quartz的集群模式 把若依项目中的quartz数据库导入到数据库中然后打开ScheduleConfig配置类复制项目启动&#xff08;记得修改端口&#xff09;&#xff0…

给自己复盘用的tjxt笔记day11第二部分

异步领券 优化方案分析 对于高并发问题&#xff0c;优化的思路有异步写和合并写。 其中&#xff0c;合并写请求比较适合应用在写频率较高&#xff0c;写数据比较简单的场景。而异步写则更适合应用在业务比较复杂&#xff0c;业务链较长的场景。 显然&#xff0c;领券业务更…

【功能自动化】使用测试套件运行测试函数

1.创建registers.py 将registers.py放在文件夹下 registers.py 代码实现 # 导入包 from selenium import webdriver from selenium.webdriver.support.select import Select from time import sleep import unittest import parameterizeddriver None file open(r"us…

ImportError:DLL load failed while importing cv2:找不到指定的模块

用pyinsatller打包好脚本执行后&#xff0c;出现上面的错误&#xff0c;这个错误很明显就是缺少了必需的dll文件&#xff0c;这个网上的资料也比较少&#xff0c;我搜了很久也没找出能解决的方法。 方法1 看官网&#xff1a;https://pypi.org/project/opencv-python/ 拉倒下…

MDS100-16-16-ASEMI三相整流模块MDS100-16

编辑&#xff1a;ll MDS100-16-16-ASEMI三相整流模块MDS100-16 型号&#xff1a;MDS100-16 品牌&#xff1a;ASEMI 封装&#xff1a;M18 批号&#xff1a;2024 类型&#xff1a;整流模块 电流&#xff1a;100A 电压&#xff1a;1600V 安装方式&#xff1a;直插式封装 …

IDEA没有SQL语句提示

解决已经在IDEA连接数据库&#xff0c;但是写SQL语句不会提示列名、属性之类的 Mapper 映射没有 SQL 提示 设置中搜索&#xff0c;把方言改成 MySQL SQL Dialects

Requestium - 将Requests和Selenium合并在一起的自动化测试工具

Requests 是 Python 的第三方库&#xff0c;主要用于发送 http 请求&#xff0c;常用于接口自动化测试等。 Selenium 是一个用于 Web 应用程序的自动化测试工具。Selenium 测试直接运行在浏览器中&#xff0c;就像真正的用户在操作一样。 本篇介绍一款将 Requests 和 Seleniu…

谷粒商城实战笔记-281-商城业务-订单服务-锁定库存

文章目录 一&#xff0c;锁定库存的基本逻辑二&#xff0c;具体实现 创建订单时&#xff0c;有一个非常重要的步骤&#xff0c;就是锁定库存&#xff0c;或者称之为预占库存。 尽管还没有卖出去&#xff0c;但是因为订单已经创建&#xff0c;所以要确保这个订单对应商品是有库…

最后一波,漂亮、简洁的登录页面模板分享,拿来即用(三)

文章目录 前言一、很有质感的jQuery登录模板二、纯CSS实现的清凉风格的登录三、基于layui的后台管理登录模板四、jQuery个性化登录模板五、带下雪背景的登录注册页面 前言 在做管理系统的时候&#xff0c;有时为了做一个漂亮简洁的登录页面&#xff0c;对应擅长搞后端开发的老…

15行为型设计模式——责任链模式

一、责任链模式简介 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;也叫职责链模式或者职责连锁模式。用于处理请求的多个对象&#xff0c;以实现请求的分发和处理。它的核心思想是将请求的处理职责链式地传递给多个对象…

NRP-Z24功率探头RS/NRP-Z23详情参数NRP-Z21功率传感器

USB 功率传感器&#xff1a; NRP-Z11 频率范围&#xff1a;10 MHz - 8 GHz 功率范围&#xff1a;-67 dBm to 23 dBm. NRP-Z21 频率范围&#xff1a;10 MHz - 18 GHz 功率范围&#xff1a;-67 dBm to 23 dBm. NRP-Z22 频率范围&#xff1a;10 MHz - 18 GHz 功率范围&#xff…