OpenStack与Kubernetes共存架构实战:网络、存储与多租户打通指南
1. 为什么要把 OpenStack 和 Kubernetes 放在同一个机房里
如果你在运维圈待过几年,大概率见过这样的场景:公司早期用 OpenStack 搭了一套私有云,虚拟机跑得好好的,业务部门突然说"我们要上容器化,要 K8s"。于是运维团队面临一个经典抉择——是把 OpenStack 拆了全量迁到 K8s,还是让两套系统各管一摊、并行运行?
我经历过三次这样的技术栈共存改造,踩过的坑足够写一本小册子。先说结论:OpenStack 和 Kubernetes 不是替代关系,在相当长的时间内它们是互补的。OpenStack 擅长的是 IaaS 层——虚拟机、裸金属、块存储、网络虚拟化、租户隔离,这些能力经过十几年打磨已经非常成熟。Kubernetes 擅长的是 PaaS 层——容器编排、服务发现、弹性伸缩、声明式 API。两者解决的是不同层次的问题。
那为什么很多人觉得它们"冲突"?因为两者在资源管理、网络模型、存储抽象上确实存在重叠区域。比如 OpenStack 的 Neutron 和 K8s 的 CNI 都在管网络,Cinder 和 CSI 都在管存储,Nova 和 Kubelet 都在管计算资源调度。如果不在架构层面做好边界划分,运维会陷入"两套系统互相打架"的泥潭。
这篇文章面向的是正在做或准备做 OpenStack 与 K8s 共存架构的运维工程师、云平台架构师。我会从实际部署经验出发,讲清楚三件事:两者共存的典型架构模式有哪些、每种模式下的网络和存储怎么打通、以及我在真实环境中踩过的那些坑。不会只讲概念,每个环节都会给出可复现的操作路径和参数说明。
提示:本文假设读者已经具备 OpenStack 和 Kubernetes 的基础操作能力,不会从零讲解如何安装 OpenStack 或初始化 K8s 集群。如果你还在
kubeadm init阶段,建议先跑通单集群再来看共存方案。
2. 三种共存架构模式的实际选型对比
2.1 模式一:K8s 跑在 OpenStack 虚拟机之上
这是最保守也最容易落地的方案。OpenStack 作为底层 IaaS 提供虚拟机,K8s 集群的 master 和 worker 节点全部是 OpenStack 的 instance。网络走 Neutron 的 tenant network,存储用 Cinder volume 挂给虚拟机做本地盘或直接对接 CSI。
这种模式的优势非常明显:运维边界清晰。OpenStack 团队管虚拟机和网络,K8s 团队管容器和编排,两边通过 API 交互。资源隔离靠 OpenStack 的 project/quota 机制保证,K8s 集群挂了也不影响其他租户。
但缺点同样突出。首先是性能损耗:容器网络经过一层虚拟化,叠加 overlay 之后延迟明显上升。我实测过,同样配置下裸金属 K8s 的 Pod 间 P99 延迟约 0.3ms,跑在 OpenStack 虚拟机上的 K8s 约 0.8-1.2ms。对于延迟敏感型业务(如实时风控、高频交易),这个差距不可接受。其次是资源利用率:虚拟机预留的资源无法被 K8s 动态回收,容易出现"虚拟机利用率 40% 但 K8s 集群资源不足"的尴尬。
适合场景:中小规模容器化、对性能不敏感的内部系统、团队 K8s 经验不足需要快速上手的阶段。
2.2 模式二:K8s 直接管理裸金属,与 OpenStack 共享物理资源池
这个模式在近两年越来越流行,核心思路是用 K8s 的裸金属管理能力(如 Metal3、Tinkerbell)直接纳管物理机,OpenStack 则继续管理另一批物理机上的虚拟机。两者共享同一个数据中心网络和存储后端,但计算资源池物理隔离。
具体做法通常是:机房里的物理机分成两组,一组跑 OpenStack 控制面 + 计算节点,另一组作为 K8s 的 bare metal node。网络层面通过 spine-leaf 架构打通,存储层面共用 Ceph 集群——OpenStack 通过 Cinder 的 Ceph driver 使用 RBD,K8s 通过 Ceph CSI 使用同一套集群。
这种模式的关键在于存储和网络的统一。我强烈建议在这个模式下把 Ceph 作为统一存储底座,原因有三:第一,Ceph 同时支持 RBD(块)、CephFS(文件)、RGW(对象),能覆盖 OpenStack 和 K8s 的所有存储需求;第二,Ceph 的 CRUSH 算法天然支持多租户隔离,可以通过 pool 和 namespace 做资源划分;第三,运维一套 Ceph 比维护 Cinder 后端 + K8s CSI 两套存储系统省心得多。
网络方面,OpenStack 用 Neutron + OVS/OVN,K8s 用 Calico 或 Cilium。两者在物理网络层面通过 VLAN 或 VXLAN 打通,但逻辑上保持独立。这里有个容易忽略的细节:MTU 必须全局一致。如果 OpenStack 的 VXLAN MTU 是 1450,K8s 的 Calico IPIP MTU 是 1440,跨系统通信时会出现分片和丢包。我的做法是统一规划为 1450,并在所有物理交换机上配置 jumbo frame。
2.3 模式三:OpenStack 作为 K8s 的 IaaS 控制面(Magnum 方案)
OpenStack Magnum 是官方提供的容器编排服务,它本质上是在 OpenStack 上自动化部署和管理 K8s 集群。你通过 Magnum API 创建 cluster template 和 cluster,Magnum 会调用 Heat 编排虚拟机、调用 Neutron 创建网络、调用 Cinder 创建存储,最后在虚拟机上自动部署 K8s。
这个方案的优势是与 OpenStack 生态深度集成:认证走 Keystone、网络走 Neutron、存储走 Cinder、监控走 Ceilometer。对于已经重度使用 OpenStack 的企业,Magnum 能最大程度复用现有运维体系。
但 Magnum 的坑也不少。首先是版本滞后:Magnum 支持的 K8s 版本通常比社区最新版晚 2-3 个大版本。我上次部署时 Magnum 最高支持 K8s 1.24,而社区已经到 1.28 了。其次是定制困难:Magnum 的 cluster template 虽然可以传一些参数,但想深度定制 kubelet 参数、改 CNI 插件、加自定义 admission controller,就得改 Magnum 的 driver 代码,维护成本很高。第三是故障排查链路长:K8s 出问题时要先查 Magnum,再查 Heat,再查 Nova,最后才到 K8s 本身,定位效率低。
我的建议是:除非你的团队对 OpenStack 非常熟悉且没有强定制需求,否则优先考虑模式二。模式二在性能、灵活性和运维效率上综合最优,虽然初期架构设计复杂一些,但长期收益明显。
| 对比维度 | 模式一:K8s on VM | 模式二:裸金属并行 | 模式三:Magnum |
|---|---|---|---|
| 网络延迟 | 高(叠加虚拟化) | 低(接近裸金属) | 高(同模式一) |
| 资源利用率 | 低 | 高 | 低 |
| 运维复杂度 | 低 | 中 | 高(链路长) |
| K8s 版本灵活性 | 高 | 高 | 低(受 Magnum 限制) |
| 与 OpenStack 集成度 | 中 | 低 | 高 |
| 适合规模 | 中小 | 中大型 | 中小 |
3. 网络打通:Neutron 与 CNI 的边界怎么划
3.1 先搞清楚两者管的是什么
很多人把 Neutron 和 CNI 混为一谈,觉得都是"管网络的"。实际上它们的职责层次完全不同。Neutron 管的是虚拟网络基础设施:网络(network)、子网(subnet)、端口(port)、路由器(router)、安全组(security group)、浮动 IP(floating IP)。它面向的是虚拟机和裸金属服务器,提供的是 L2/L3 连通性和租户隔离。
CNI 管的是容器网络接口:Pod 的 IP 分配、Pod 间通信、Service 的负载均衡、NetworkPolicy 的访问控制。它面向的是 Pod 和 Service,工作在容器的 network namespace 层面。
两者在物理网络之上是叠加关系:Neutron 提供底层连通性,CNI 在其上构建容器网络。理解这一点,后面的配置就不会乱。
3.2 跨系统通信的三种典型场景
场景一:K8s Pod 访问 OpenStack 虚拟机上的服务。这是最常见的需求,比如 K8s 里的微服务要调用 OpenStack 虚拟机上的数据库。做法是在 Neutron 里给虚拟机分配一个 provider network 的 IP(不走 overlay),K8s 侧通过 Calico 的 ipPool 配置把该网段加入可路由范围。具体操作是在 Calico 的 IPPool 资源里添加 allowedUses 或直接用 BGP 宣告路由。
场景二:OpenStack 虚拟机访问 K8s Service。这个稍微麻烦,因为 K8s Service 的 ClusterIP 是虚拟 IP,默认只在集群内部可路由。解决方案有两种:一是用 NodePort 暴露服务,虚拟机通过节点 IP + NodePort 访问;二是用 MetalLB 给 Service 分配外部 IP,然后在 Neutron 的路由器上添加静态路由指向 K8s 节点。我通常推荐 MetalLB 方案,因为 IP 管理更清晰。
场景三:K8s Pod 与 OpenStack 虚拟机在同一网段直接通信。这需要把 K8s 的 Pod CIDR 和 Neutron 的 subnet CIDR 规划到同一个大网段下,且 CNI 使用 underlay 模式(如 Calico 的 BGP 模式或 Cilium 的 native routing 模式)。这种方案性能最好,但 IP 规划要非常谨慎,一旦冲突排查起来很痛苦。
3.3 MTU 和路由的实操配置
MTU 问题我在前面提过,这里给出具体配置。假设物理网络 MTU 是 9000(jumbo frame),OpenStack 的 VXLAN 封装开销是 50 字节,K8s 的 Calico IPIP 封装开销是 20 字节。那么:
- 物理网卡 MTU:9000
- Neutron VXLAN 网络 MTU:8950
- Calico IPIP 隧道 MTU:8930
配置命令如下(以 Calico 为例):
Neutron 侧的 MTU 在 neutron.conf 里配置:
路由打通方面,如果 K8s 节点和 OpenStack 虚拟机在不同子网,需要在 Neutron 路由器上添加静态路由:
注意:添加路由前务必确认 K8s 节点的 IP 转发已开启(
net.ipv4.ip_forward=1),否则路由添加了也不通。这个坑我踩过,排查了两个小时才发现是 sysctl 没开。
4. 存储统一:Cinder 与 CSI 如何共用一套 Ceph
4.1 为什么存储统一比网络统一更关键
网络不通顶多是访问不了,存储不统一会导致数据孤岛。我见过太多环境:OpenStack 用一套 Ceph,K8s 用另一套 Ceph,结果虚拟机上的数据要迁到容器里,得走一遍导出导入,费时费力还容易出错。更麻烦的是备份和容灾策略要维护两套,运维成本翻倍。
统一存储底座的价值在于:数据可以在虚拟机和容器之间自由流动。同一个 Ceph 集群,OpenStack 通过 Cinder 创建 volume 挂给虚拟机,K8s 通过 CSI 创建 PVC 挂给 Pod,两者底层都是 RBD image,甚至可以通过 rbd map 在物理机上直接访问。
4.2 Ceph 集群的规划要点
统一 Ceph 集群的规划有几个关键决策:
Pool 划分。我通常创建三个 pool:volumes 给 Cinder 用,vms 给 Nova 的 ephemeral disk 用,kubernetes 给 K8s CSI 用。每个 pool 设置不同的 PG 数量和副本数。volumes 和 kubernetes 用 3 副本保证数据安全,vms 可以用 2 副本降低成本。
认证隔离。Cinder 用 cinder 用户,K8s CSI 用 kubernetes 用户,通过 Ceph 的 caps 机制限制权限。比如:
这样即使 K8s 侧的凭证泄露,也访问不了 Cinder 的 pool。
网络分离。Ceph 的 public network 和 cluster network 要分开,public 走业务网,cluster 走存储专用网(万兆或 25G)。如果 K8s 节点和 OpenStack 节点共用 Ceph,确保两者到 Ceph 的网络延迟一致,否则会出现"一边快一边慢"的性能不均。
4.3 Cinder 和 CSI 的对接配置
Cinder 对接 Ceph 是成熟方案,在 cinder.conf 里配置:
K8s 侧用 Ceph CSI,需要部署 ceph-csi-rbd 的 provisioner 和 node plugin。核心配置在 StorageClass 里:
这里有个细节:imageFeatures 建议设为 layering,这样支持 RBD 的快照和克隆。如果要做跨系统数据迁移,可以用 rbd clone 从 Cinder 的 volume 快速克隆一个 image 给 K8s 的 PVC 用,秒级完成,比导出导入快几个数量级。
4.4 跨系统数据迁移的实操路径
假设你有一个 OpenStack 虚拟机上的 MySQL 数据盘(Cinder volume),想迁到 K8s 的 PVC 里。步骤如下:
- 在 Ceph 里找到该 volume 对应的 RBD image:
rbd ls volumes | grep <volume-id> - 创建快照:
rbd snap create volumes/<image-id>@migrate - 保护快照:
rbd snap protect volumes/<image-id>@migrate - 克隆到 K8s pool:
rbd clone volumes/<image-id>@migrate kubernetes/<new-image> - 在 K8s 里创建 PV 指向该 image,或直接用 CSI 的
static provisioning方式挂载
整个过程数据不落地,纯 Ceph 内部操作,TB 级数据也能在几分钟内完成。这个技巧我在一次紧急迁移中用过,业务停机时间控制在 5 分钟以内。
5. 身份认证与多租户的打通思路
5.1 Keystone 和 K8s RBAC 的映射关系
OpenStack 的认证体系是 Keystone,核心概念是 domain、project、user、role。K8s 的认证体系是 RBAC,核心概念是 user、group、role、rolebinding。两者要打通,本质是把 Keystone 的 project 映射为 K8s 的 namespace,把 Keystone 的 role 映射为 K8s 的 ClusterRole。
实现方式通常是部署一个 keystone-auth webhook,让 K8s 的 API Server 在认证时调用 Keystone 验证 token。具体配置在 kube-apiserver 的启动参数里:
keystone-webhook.yaml 里配置 Keystone 的 endpoint 和 CA 证书。这样用户用 OpenStack 的 token 就能直接访问 K8s API,不需要维护两套账号体系。
5.2 多租户隔离的实际边界
打通认证之后,多租户隔离的边界要划清楚。我的做法是:
- OpenStack 侧:每个租户一个 project,配额限制 vCPU、内存、存储、浮动 IP 数量
- K8s 侧:每个租户一个 namespace,配合 ResourceQuota 和 LimitRange 限制资源
- 网络侧:OpenStack 用 tenant network 隔离,K8s 用 NetworkPolicy 隔离
- 存储侧:Ceph 用 pool 或 namespace 隔离,配合 caps 限制访问
这里有个容易忽略的点:K8s 的 NetworkPolicy 默认是"允许所有",必须显式配置 deny-all 再逐条放行。我见过因为没配默认拒绝策略导致租户间 Pod 可以互相访问的安全事件。建议每个 namespace 创建时自动注入一个 deny-all 的 NetworkPolicy:
5.3 配额与资源争抢的处理
OpenStack 和 K8s 各自有配额系统,但两者不互通。可能出现 OpenStack 配额还剩很多、K8s 配额已满,或者反过来。我的经验是在 Ceph 和物理网络层面做最终兜底:Ceph 的 pool 设置 max_bytes 限制总容量,物理交换机做 QoS 限制带宽。这样即使上层配额系统失灵,底层也不会被击穿。
另外建议部署一个统一的监控面板,把 OpenStack 的 ceilometer 数据和 K8s 的 metrics-server 数据聚合到同一个 Grafana 里。我用 Prometheus 同时抓取两边的 metrics,配置了跨系统的告警规则,比如"当 Ceph 集群使用率超过 80% 时,同时检查 OpenStack 和 K8s 的存储配额使用情况"。
6. 我在真实环境中踩过的五个坑
6.1 坑一:Neutron 的 security group 把 K8s 的健康检查挡了
K8s 的 kubelet 会定期对 Pod 做 liveness 和 readiness 探针,这些探针从节点 IP 发出。如果 OpenStack 虚拟机的 security group 没有放行节点 IP 的探针端口,Pod 会被反复重启。我当时的现象是 Pod 一直 CrashLoopBackOff,查日志发现探针超时,但手动 curl 又是通的。最后发现是 security group 只放行了特定源 IP,没放行 K8s 节点网段。
解决方案是在 security group 里添加规则,放行 K8s 节点 CIDR 到探针端口。或者更优雅的做法是用 hostNetwork: true 让探针走宿主机网络,但这样会占用宿主机端口,要权衡。
6.2 坑二:Ceph 的 rbd_cache 导致数据不一致
Cinder 和 CSI 同时访问 Ceph 时,如果两边都开了 rbd_cache,可能出现缓存不一致。我遇到过一次:虚拟机写入数据后,K8s 的 Pod 读到的还是旧数据。排查后发现是 Cinder 侧的 cache 没刷新。
解决方案是对跨系统共享的 image 禁用 cache,或者在应用层做 fsync。Ceph 的 rbd_cache 默认是开的,可以在 ceph.conf 里针对特定 pool 关闭:
但关闭 cache 会影响性能,所以我的建议是:跨系统共享的 volume 禁用 cache,系统内部使用的 volume 保持开启。
6.3 坑三:K8s 节点重启后 Calico 路由丢失
K8s 节点重启后,Calico 的 BGP 路由有时不会自动恢复,导致跨节点 Pod 通信中断。这个问题的根因是 Calico 的 felix 在节点启动时可能比网络就绪早,导致路由宣告失败。
解决方案是给 Calico 的 DaemonSet 加 initContainer,等待网络就绪后再启动 felix。或者配置 FelixConfiguration 的 routeRefreshInterval 缩短路由刷新周期:
6.4 坑四:OpenStack 的 nova-compute 和 K8s 的 kubelet 抢 CPU
在模式二(裸金属并行)下,如果 OpenStack 计算节点和 K8s 节点混部,nova-compute 和 kubelet 会争抢 CPU 资源。我见过 nova-compute 的 CPU 占用飙到 100%,导致虚拟机性能骤降。
解决方案是用 cgroup 或 systemd 做资源隔离。给 nova-compute 设置 CPUQuota,给 kubelet 设置 --system-reserved 和 --kube-reserved:
6.5 坑五:跨系统的 DNS 解析混乱
OpenStack 虚拟机用 dnsmasq 或 designate 做 DNS,K8s 用 CoreDNS。两者如果不打通,会出现"虚拟机解析不了 K8s Service 域名,Pod 解析不了虚拟机主机名"的问题。
我的做法是在 CoreDNS 里配置 forward 到 OpenStack 的 DNS,在 Neutron 的 subnet 里配置 DNS 指向 CoreDNS 的 Service IP。具体配置:
Neutron 侧:
这样双向解析就通了。注意 CoreDNS 的 Service IP 要确保从 OpenStack 网络可达,通常用 NodePort 或 MetalLB 暴露。
7. 监控与故障排查的跨系统实践
7.1 统一监控栈的搭建
我用的方案是 Prometheus + Grafana + Alertmanager,同时抓取 OpenStack 和 K8s 的 metrics。OpenStack 侧通过 ceilometer 的 prometheus exporter 暴露指标,K8s 侧用 kube-state-metrics 和 node-exporter。
关键配置是 Prometheus 的 scrape_configs:
Grafana 里我建了一个"跨系统总览"面板,把 OpenStack 的虚拟机数量、K8s 的 Pod 数量、Ceph 的容量使用率放在同一屏。这样一眼就能看出资源瓶颈在哪一层。
7.2 故障排查的决策树
跨系统故障排查最怕"不知道问题在哪一层"。我总结了一个决策树:
- 先看 Ceph 健康状态:
ceph -s,如果HEALTH_ERR,先解决存储问题 - 再看网络连通性:从 K8s 节点 ping OpenStack 虚拟机,从虚拟机 ping Pod IP
- 然后看认证:
openstack token issue和kubectl auth can-i是否正常 - 最后看应用层:Pod 日志、虚拟机日志、探针状态
这个顺序能覆盖 90% 的跨系统故障。我把它做成了一个 runbook,团队新人照着走就能定位大部分问题。
7.3 日志聚合的方案
日志方面我用 Fluentd 同时收集 OpenStack 和 K8s 的日志,统一输出到 Elasticsearch。OpenStack 的日志在 /var/log/nova、/var/log/neutron 等目录,K8s 的日志通过 fluent-bit 的 DaemonSet 收集。
有个细节要注意:OpenStack 的日志格式和 K8s 的日志格式不同,在 Elasticsearch 里要建不同的 index pattern。我通常用 openstack-* 和 k8s-* 两个 pattern,在 Kibana 里做联合查询。
8. 版本兼容性与升级策略
8.1 版本矩阵的维护
OpenStack 和 K8s 的版本迭代都很快,两者共存时必须维护一个版本兼容矩阵。我的经验是:
| OpenStack 版本 | 推荐 K8s 版本 | 备注 |
|---|---|---|
| Train | 1.18-1.20 | Magnum 支持有限 |
| Ussuri | 1.20-1.22 | 稳定组合 |
| Victoria | 1.22-1.24 | 推荐 |
| Wallaby | 1.24-1.26 | 当前主流 |
| Xena | 1.26-1.28 | 较新 |
这个矩阵不是绝对的,但遵循一个原则:K8s 版本不要超过 OpenStack 版本发布时社区验证过的范围。比如 Wallaby 发布时 K8s 最新是 1.26,那你就不要在这个 OpenStack 版本上跑 1.28。
8.2 升级顺序与回滚方案
升级时先升 K8s 再升 OpenStack,因为 K8s 的升级通常更平滑,且 K8s 对底层 IaaS 的依赖较小。具体步骤:
- 备份 etcd 和 Ceph 的 CRUSH map
- 升级 K8s 的 control plane(逐个节点)
- 升级 K8s 的 worker 节点(drain 后升级再 uncordon)
- 验证 K8s 集群正常
- 升级 OpenStack 的 control plane(逐个服务)
- 升级 OpenStack 的计算节点(迁移虚拟机后升级)
回滚方案要提前准备好:K8s 用 etcd 快照回滚,OpenStack 用数据库备份回滚。我建议在测试环境完整演练一遍升级流程再上生产。
8.3 长期维护的建议
共存架构的长期维护,我的核心建议是尽量减少两者的耦合点。耦合点越少,升级时互相影响越小。具体做法:
- 网络层用标准协议(BGP、VXLAN)对接,不用私有 API
- 存储层用 Ceph 的标准接口(RBD、CephFS),不用定制 driver
- 认证层用标准 webhook,不用魔改 API Server
- 监控层用标准 exporter,不用定制采集器
这样即使一边升级,另一边也不受影响。我在一个跑了三年的共存环境里验证过这个原则,期间 OpenStack 从 Queens 升到 Wallaby,K8s 从 1.14 升到 1.26,业务没有中断过。
最后分享一个我在实际操作中的体会:共存架构的成功关键不在于技术多先进,而在于边界划得清不清楚。我见过技术栈很新但边界混乱的环境,运维天天救火;也见过技术栈偏老但边界清晰的环境,稳定运行好几年。把 Neutron 和 CNI 的边界、Cinder 和 CSI 的边界、Keystone 和 RBAC 的边界想清楚,比追新版本重要得多。
相关推荐
基于Python+Open CV的手势识别算法设计
伴随着人工智能时代的到来,人机交互的领域也逐渐成为研究的一大方向;其中,手势识别是人机交互领域的一项关键技术,自此手势识别也迎来了一波高潮,近几年无论是在消费领域、电子领域、数码领域、家电领域甚至汽车领域上,都能或多或少的见到手势识别的身影。 手势识别在设计智能高效的人机界面方面具有至关重要的作用, 目前手势识别已应用到手语识别、智能监控、到虚拟现实等各个领域,手势识别的原理都是利用各种传感器(例如红外、摄像头等)对手部的形态进行捕捉并进行建模,形成一个模型信息的序列帧,而后将这些信息序列转换为机器能够识别的相对应指令(例如打开、切换菜单、移动等)来完成控制。 采用Python的集成开发环境Pycharm进行本次课程设计,在Pycharm中进行需要库(模块)的下载,调取电脑摄像头,按帧读取摄像头采集到的头像,形态学处理,图像旋转(由于摄像头采集到的图像是镜像,需要用cv2.flip将摄像头采集到的图像进行处理),选取图片中固定位置作为手势输入,用红线画出手势识别框,基于hsv的肤色检测,进行高斯滤波,找出轮廓,求出图像中手势的凹凸点,手指间角度求取。
ROS-CV-ImageConverter:将ROS图像转换为OpenCV(cv :: Mat)类型的图像
ROS-CV图像转换器 依存关系 cv_bridge(ROS软件包)
计算机视觉图像处理-CV2与图像插值算法
用最近邻插值与双线性插值原理完成图像缩放 最近邻插值,是指将目标图像中的点,对应到源图像中后,找到最相邻的整数点,作为插值后的输。缺点:使用最近邻插值算法处理图像放大时,在图象中可能出现明显的块状效应 双线性插值,在两个方向上做三次线性插值。使用双线性插值算法处理图像放大时,在图象中可能出现马赛克 代码 import cv2 img = cv2.imread(’./xiabang.jpg’, cv2.IMREAD_UNCHANGED) #缩放比例 scale_percent = 0.3 width = int(img.shape[1] * scale_percent) height = int
基于水平集CV模型的图像分割(Matlab代码)
基于水平集CV模型的图像分割(Matlab代码),全套代码
导向滤波(guide_filter)的python实现
导向滤波(guide_filter)的python实现,可以结合暗通道;理论实现比较好的图像去噪效果。

