Redis速记:从安装到分布式锁,一篇理清核心知识点

RedisRedis数据类型Redis安装 本内容遵循CC 4.0 BY-SA版权协议
生命的光彩 生命的光彩 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要

做后端这些年,我观察到一个很有意思的现象:网上关于Redis的热搜词常年集中在“redis下载”“redis数据类型”“redis安装”和“redis面试题”这一层,说明大部分人刚接触Redis时真正缺的不是源码,而是一份能看得进去、记得住的速记。这篇Redis速记,我就按自己带项目时梳理知识的方式,把从环境搭建到数据结构、从缓存治理到分布式锁、再到面试常考原理的关键点串成一条线,尽量说人话、给结论,也把那些不写进官方文档的坑标出来。既有刚入门就能照着操作的步骤,也有你遇到问题后回来翻的排查思路。

1. 先把Redis的定位想清楚,速记才有主线

1.1 Redis不只是一个缓存

很多教程第一句就是“Redis是高性能缓存数据库”,这话没错,但容易把人带偏。你要是只把它当缓存用,后面遇到分布式锁、排行榜、自动补全这些场景时,就总感觉命令记不住,因为没有一个统一的主线去理解它。

我更愿意把Redis看成一张“放在内存里的数据结构表”。它的每个value都是有明确结构的:字符串、哈希、列表、集合、有序集合,以及新版本里扩展的位图、基数统计、地理坐标和流。正因为结构清晰,它才能干很多数据库和普通缓存干不了的事。比如MySQL要查一个排行榜,得order by再limit,一旦数据量大,数据库压力就上去了;而Redis里一个ZSet直接用索引取区间,毫秒级返回。这里的关键不是“内存快”,而是“结构对口”。

生活里类比一下:MySQL像一个档案室,资料齐全但每次翻找都要动腿;Redis像你工作台上的一排便利贴,贴什么结构、怎么排序,一眼就清楚。便利贴虽小,但能不能用得顺手,取决于你按什么规则贴它,这就是数据结构和命令设计的意义。

1.2 速记主线:数据结构-命令-机制-场景

我梳理Redis知识的顺序是:先按数据结构去记命令,再理解过期、淘汰、持久化这些底层机制,然后把机制用到缓存治理、分布式锁这类场景里,最后再从面试题往回推原理。这条线和很多人“从命令大全第一页开始背”的路线比,最大的差别是,每个知识点都能挂在另一层上,形成因果链。

比如,为什么要记EXPIRE过期命令?因为你迟早会遇到缓存雪崩,而缓存雪崩的一个常见解决方案就是给过期时间加随机抖动。为什么面试爱问“Redis为什么单线程还快”?因为你想说明白内存、IO多路复用和避免上下文切换,这决定你在系统里敢不敢把高并发请求放心交给它。下表是我平时带新人时给出的一条速记路径,你也可以按这个顺序走:

学习主题 核心问题 常见坑
数据结构与命令 每种结构解决什么场景 只背命令,不背选型
过期与淘汰 内存满时Redis怎么做 不设maxmemory导致OOM
持久化 重启后数据还在吗 RDB和AOF混淆
高可用 主挂了自己能恢复吗 只有主从没有哨兵
场景设计 分布式锁、缓存一致性 直接setnx+expire

下面我就按这条主线展开,先解决环境,再讲数据结构,接着进入缓存治理和业务场景,最后补上日常运维和面试原理。你可以把它当目录用,哪块薄弱就跳到哪里。

2. 环境搭建不迷路:Windows下载、Docker部署与配置文件关键项

2.1 Windows下装Redis的几条路子

如果你只是本地练习,Windows下最常见的做法是去Redis官网下载源码包或Windows维护版。注意,官方发行版并没有直接维护Windows二进制,官网上的download更多指向Linux源码。你在Windows上装Redis,通常有三条路:

  1. 使用第三方维护的Windows发行版,比如tporadowski的Redis for Windows,解压后直接运行redis-server.exe;
  2. 通过包管理工具,比如choco install redis-64;
  3. 老老实实走WSL,在Linux子系统里按Linux方式装,这样和生产环境最接近,后续不会出现“本地通、线上不通”的尴尬。

本地练习我更推荐第三种。原因很简单:生产环境基本是Linux或容器,Windows版的Redis内核版本往往落后,很多新特性(比如Stream)体验不到,而且你在Windows上学到的操作习惯,到线上还得改一遍。

如果你已经拿到Windows版安装包,流程一般是:解压到指定目录,用命令行进入目录执行redis-server.exe,再另开一个终端窗口执行redis-cli.exe ping,看到PONG就说明通了。想开机自启,可以用redis-server --service-install redis.windows.conf注册成Windows服务,后续用--service-start、--service-stop管理。

2.2 Docker Compose部署:从单机到主从

工作中我更常用Docker一键拉起。下面给一个既能跑单机、又能快速扩成主从的docker-compose.yml:

YAML
version: "3.8"
services:
redis-master:
image: redis:7.0
container_name: redis-master
ports:
- "6379:6379"
command: ["redis-server", "--appendonly", "yes", "--requirepass", "yourpassword"]
volumes:
- ./data/master:/data
redis-replica:
image: redis:7.0
container_name: redis-replica
ports:
- "6380:6379"
depends_on:
- redis-master
command: ["redis-server", "--replicaof", "redis-master", "6379", "--masterauth", "yourpassword", "--requirepass", "yourpassword"]
volumes:
- ./data/replica:/data

这里最关键的是replica容器的两个参数:--replicaof redis-master 6379表示从节点要同步的目标;--masterauth yourpassword是因为主节点开了requirepass,从节点同步时必须带密码认证。两个容器都在同一个compose网络里,所以直接写服务名redis-master就能访问,这也是生产环境推荐的方法。

等容器起来后,执行:

BASH
docker compose ps
docker exec -it redis-replica redis-cli -a yourpassword info replication

看到role:slave或者role:replica、master_link_status:up,就说明主从已经搭好。这个步骤也是热搜词里“docker安装redis主从”最常见的落地场景,很多新人卡在主从连不上,十有八九是masterauth没配,或者把replicaof的地址写成了外部IP。

2.3 配置文件里值得动手改的几项

用redis-server启动时,默认配置很多不适合线上。以下这几个配置项是我每次部署都会过一遍的:

配置项 作用 我的建议
bind 监听地址,默认127.0.0.1 生产按需改成内网IP,避免裸奔
protected-mode 保护模式 设置为no前必须确认网络访问控制已做好
requirepass 访问密码 必须开
appendonly 是否开启AOF持久化 数据重要就yes
maxmemory 最大内存上限 必须设,否则可能拖垮整台机器
maxmemory-policy 内存淘汰策略 按业务选,详见下文缓存治理部分

配置文件的坑主要集中在前两项。很多新手在云服务器上启动Redis没改bind和protected-mode,然后Redis日志里突然出现大量未知IP的请求,这就是被扫描了。Redis本身定位是内网组件,端口一定不要直接暴露到公网。如果确实需要外部访问,走防火墙白名单比改bind更稳妥。

3. 数据类型速查:五种基础结构加上扩展结构,选型逻辑一次说透

3.1 五种基础类型:场景、命令和记忆口诀

Redis入门最重要的是先把五种基础类型用熟。我给你一张我自己常用的速查表:

类型 适合场景 高频命令 记忆口诀
String 缓存、计数器、分布式锁、Session SET GET INCR SETNX EXPIRE 一个key一个值
Hash 对象字段、配置项、购物车 HSET HGET HGETALL HDEL 一个key多个字段
List 消息队列、最新列表、时间线 LPUSH RPUSH LPOP LRANGE LLEN 一头进一头出
Set 去重、共同好友、标签 SADD SMEMBERS SINTER SUNION 元素唯一
ZSet 排行榜、自动补全、延迟队列 ZADD ZRANGE ZRANGEBYSCORE ZREM 带权重排序

选型时最核心的一句判断是:先看数据的结构,再看需要什么操作。比如要存用户信息,第一种想法可能是把整个对象JSON序列化后塞进String,这本身没问题,但如果你需要频繁修改其中一个字段,每次都要把整个对象取出来反序列化、改完再覆盖回去,很浪费。这种场景换成Hash,一个字段对应Hash里的一个field,互不干扰,代码也更清晰。

有一点要注意:List做消息队列时,LPOP是阻塞还是非阻塞。Redis提供了BRPOP、BLPOP这种阻塞弹出命令,这也是早期很多人拿Redis当简单MQ用的原因。但它本质不是持久化消息队列,没有消费确认、消息回溯这些能力,真到业务复杂了,还是要考虑专门的消息中间件。这个判断很重要,能帮你在选型时少走弯路。

3.2 扩展结构:Bitmap、HyperLogLog、Geo和Stream

Redis在五种基础类型之外,还提供了一批“省内存的魔法结构”,面试和实战中都很加分:

  • Bitmap:本质是String的位操作,适合做签到、在线状态这种只有0和1的标记。一亿用户一天在线状态大概12.5MB,非常省。
  • HyperLogLog:用于海量数据去重统计,比如统计UV。它不存原始数据,只存基数估计,标准误差0.81%左右,比Set省太多内存,但没法精确到具体元素。
  • Geo:存经纬度坐标,支持计算两点距离、查询附近的人。底层实现是ZSet,score就是经纬度编码后的数值,所以很多Geo命令和ZSet很像。
  • Stream:Redis 5.0引入的流式数据结构,支持消费者组、消息确认、Pending List,算是官方对“用Redis做消息队列”的正规回应。

这块速记的核心不是命令本身,而是“什么时候值得用”。比如统计UV,如果你用Set,十亿用户基本不可能;换HyperLogLog,几KB就能估算百万级去重数。这类选型权衡,才是Redis真正体现价值的地方。

3.3 对象存储与序列化:为什么Redis里打开是乱码

许多初学者用可视化客户端连上Redis后,发现key前面带了一串\xac\xed\x00\x05t,value也不是能看懂的内容,第一反应是自己操作错了。其实这是因为Redis存的是二进制安全数据,它不关心你塞进去的是字符串还是Java对象的序列化字节流。

以Spring Data Redis为例,默认的RedisTemplate使用JDK序列化,对象会被编码成一堆以\xac\xed开头的字节,人眼当然看不明白。解决方法是合理配置序列化器:key使用StringRedisSerializer,value使用Jackson2JsonRedisSerializer或者GenericJackson2JsonRedisSerializer。这样key可读,value也是JSON形式,排查问题方便很多。

如果你在用Go,用得比较多的go-redis库是不强制序列化的,你可以直接传string或[]byte,也可以自己用json.Marshal转换,自由度更高,但也意味着你必须自己对“存进去的是什么格式”负责。这里我的经验是:能存JSON就存JSON,能不加对象头就别加对象头。JDK序列化虽然省事,但对象结构一变,老数据全读不出来,这是生产环境最常见的序列化事故之一。

4. 缓存治理与内存淘汰:生产环境最常被问崩的一组选择题

4.1 过期删除与内存淘汰策略

Redis的Key过期并不是“时间一到立刻消失”,它用的是惰性删除配合定期删除的策略。惰性删除是指你访问这个key时才去检查是否过期;定期删除是后台每隔一段时间抽一部分key检查删除。所以一个过期key在内存里还可能残留一段时间,这是正常现象。

更关键的是内存淘汰。如果不设置maxmemory,Redis会一直写,直到操作系统内存耗尽,被系统OOM杀掉,线上事故多数就是这么来的。设置好maxmemory之后,还要选maxmemory-policy,常见的有:

策略 含义 适用场景
noeviction 内存满后不再接受写请求,直接报错 不允许丢数据的强一致场景,不推荐常规用
allkeys-lru 所有key按最近最少使用淘汰 缓存场景常用
volatile-lru 只淘汰设置了过期时间的key 有冷热区分的缓存
allkeys-lfu 按访问频率淘汰 热点非常集中的场景
volatile-ttl 优先淘汰剩余存活时间短的key 不常用

我实际项目中,纯缓存场景用allkeys-lru最多;如果只有一部分key可以淘汰,比如用户会话,就选volatile-lru。这里有个容易被忽略的点:哪怕设了maxmemory,也不是所有key都会按预期淘汰,比如使用了持久化RDB/AOF时,fork子进程可能占用额外内存,需要给系统留出余量。通常建议maxmemory设置为物理内存的70%左右,剩余留给系统和其他进程。

4.2 缓存穿透、击穿、雪崩:识别与应对

这三个概念是缓存的“三大杀手”,也是热搜词“redis缓存治理”“redis缓存设计与高并发”的核心内容。

缓存穿透指的是查询一个根本不存在的数据,请求绕过缓存直接打到数据库。攻击者如果循环请求不存在的ID,数据库就会被打挂。应对方案有两种:一是把空结果也缓存起来,设置一个较短的过期时间,比如60秒;二是用布隆过滤器,在缓存层之前判断这个key是否存在,不存在直接返回,避免打DB。

缓存击穿是指一个热点key在过期瞬间,大量请求同时打到数据库。解决办法是互斥锁:在缓存失效后,让一个线程去数据库查,其他线程先等一会再重新查缓存。也可以做逻辑过期,value里多存一个过期时间字段,后台异步刷新真实数据。

缓存雪崩则是大量key在同一时间过期,DB压力瞬间上来。最常规的处理是在设置过期时间时加上一个随机数,比如原来是3600秒,现在变成3600加0到300秒的随机值,让过期时间错峰。另一个思路是多级缓存:本地缓存放一层,Redis放一层,DB兜底,即使Redis抖动,本地缓存还能挡住一部分量。

4.3 缓存一致性:先更新数据库还是先删缓存

这是缓存治理里最绕也最常被问的问题。主流方案是Cache Aside:读的时候先查缓存,没命中再查DB并写缓存;写的时候,先更新数据库,再删除缓存。为什么是“删缓存”而不是“更新缓存”?因为更新缓存存在并发问题:两个线程同时写,后写的可能把先写的数据覆盖成旧值,而删除缓存让下一次读去DB拉最新值,更安全。

但“先更新DB再删缓存”也有竞态窗口:一个线程更新DB后、删除缓存前,另一个线程读到了旧缓存。解决思路有几种:第一,给缓存设过期时间作为兜底,就算短暂不一致,过期后也会恢复;第二,使用延迟双删,在删除缓存后等几百毫秒再删一次,覆盖掉中间被写回旧值的可能性;第三,通过订阅数据库binlog异步删除缓存,把删除动作从业务代码里解耦出来。

我不建议把“强一致”寄托在Redis缓存上。缓存设计的目标本来就是“最终一致+高可用”。你需要在业务能接受的窗口内保持一致,而不是要求它和数据库完全同步。这个认知能帮你和产品沟通时少很多争执。

5. 事务、分布式锁与自动补全:三个使用场景的落地要点

5.1 Redis事务到底给了什么保证

很多从MySQL背景过来的人,以为Redis的MULTI/EXEC和MySQL事务一样支持回滚,这是最大的误解。Redis事务只是把多个命令按顺序打包执行,中间不会插入其他客户端命令,但它不支持回滚。比如:

BASH
MULTI
SET user:1 "zhang"
INCR user:1
EXEC

第二个命令在运行时才会报错(对字符串执行INCR),但前面成功执行的命令不会回滚,结果是user:1被写成了zhang,INCR报错。Redis作者不提供回滚的理由是:大部分命令错误在入队阶段就能发现,真正运行时错误属于编程层问题,事务回滚会让Redis内部实现复杂很多、性能下降,但不带来多大收益。

所以使用Redis事务时,我的习惯是把它当成“命令打包执行”来用,而不是数据库级事务。想要更强的原子性,用Lua脚本更合适,因为脚本中的多条命令也会被整体原子执行,还能读改写。下面这个例子用Lua实现扣减库存:

LUA
local stock = tonumber(redis.call('GET', KEYS[1]))
if stock <= 0 then
return -1
end
redis.call('DECR', KEYS[1])
return stock - 1

5.2 分布式锁:从入门到能用的正确姿势

分布式锁是Redis最经典的场景之一,也是面试高频题。最基础的命令是:

BASH
SET lock:order:1001 "unique-token" NX EX 30

NX保证key不存在时才设置成功,EX设置过期时间,unique-token用于区分持有者。正确释放锁要Lua脚本保证“先比较再删除”是原子的:

LUA
if redis.call('GET', KEYS[1]) == ARGV[1] then
return redis.call('DEL', KEYS[1])
else
return 0
end

如果不能比较就直接DEL,会存在误删别人锁的问题:A的锁过期后,B抢到锁,A这时执行DEL,把B的锁删了,事务就乱了。

实际项目里我建议直接用Redisson这类库,它带看门狗机制,会自动续期,避免业务没执行完锁就过期被其他线程抢走。但要注意的是,Redis主从架构下,如果master还没把锁同步到从节点就宕机了,会存在锁丢失问题。很多公司接受这个风险,因为业务量没大到那个程度;如果你必须追求绝对安全,就要研究RedLock或者换用其他分布式协调服务。不要在简历上写“用过Redis分布式锁”但说不清这些权衡,面试官一问就露馅。

5.3 自动补全与分页:ZSet的两个实用思路

热搜词里有“使用redis构建自动补全组件”和“redis分页”,这里一并说。自动补全的核心是:用户输入前缀时,快速返回候选词。实现上可以用ZSet加ZRANGEBYLEX,把候选词放进集合,按键值查找前缀区间:

BASH
ZADD auto:city 0 "beijing" 0 "beihai" 0 "shanghai"
ZRANGEBYLEX auto:city "[be" "[bf"

score统一存0,member按字典序排列,ZRANGEBYLEX就是按字典序范围取。需要注意,用这个方案时member必须是同一个score,且数据量不要过于巨大,它是按字典树扫描的,量太大时内存吃不消。

分页则是两种常见姿势:List分页用LRANGE key start stop,start和stop是list下标;ZSet分页用ZRANGE key start stop带WITHSCORES,适合按分数排序的场景。这里有个坑:LRANGE和ZRANGE的偏移量如果很大,时间复杂度是O(N),动辄翻到几万页时性能会下降。所以Redis适合做“浅分页”,深分页还是交给搜索引擎或者数据库。

6. 可视化客户端、日志与诊断命令:日常排障工具箱

6.1 客户端选择:Redis Desktop Manager还是Another Redis Desktop Manager

连接工具几乎是每个开发者的刚需。Redis Desktop Manager一度是最流行的可视化客户端,但新版本已经转为商业授权。看到“another redis desktop manager”这个词出现在热搜里,说明大家已经在找免费替代品。

Another Redis Desktop Manager是个开源跨平台客户端,支持Windows、macOS和Linux,功能上足够日常使用:可以直观浏览key列表、根据类型筛选、查看过期时间、执行命令行、分析内存占用。下载后配置连接时,填host、port、password即可,如果Redis开启了TLS,还需要设置证书。我自己的习惯是,本地连测试环境用它,线上一般只用命令行工具,尽量少连可视化,减少事故面。

6.2 Redis日志与慢查询:怎么定位线上问题

Redis日志通常通过logfile配置,级别由loglevel控制,一般有debug、verbose、notice、warning。线上用notice或warning,避免debug刷爆磁盘。但日志只能看到启动、连接、错误这类信息,想定位慢命令,更常用的是慢查询日志。

Redis会把执行时间超过阈值的命令记录在慢日志里,阈值由slowlog-log-slower-than控制,单位微秒,默认10000微秒即10毫秒。线上为了抓慢命令,可以调到1000甚至500。查看方式:

BASH
SLOWLOG GET 10
CONFIG SET slowlog-log-slower-than 500

另外一个常见操作误区是直接用KEYS *遍历全库,数据量大时会阻塞Redis主线程,导致线上卡顿。正确做法是用SCAN,分批游标遍历,每次返回一部分key,不会长时间阻塞。比如:

BASH
SCAN 0 MATCH user:* COUNT 100

MONITOR命令能实时打印所有请求,但同样会拖垮性能,不到万不得已不要在生产开。

6.3 INFO、MEMORY和连接排查

排查Redis内存问题,第一反应应该是INFO memory,里面有used_memory、used_memory_human、maxmemory等关键指标。排查谁占着内存,可以用MEMORY USAGE key查看单key占用;要找大key,用redis-cli --bigkeys做一次扫描,它会统计每种类型里最大的几个key,这是异常上线的“后悔药”。

连接问题则看INFO clients,里面connected_clients是当前连接数,blocked_clients是被阻塞的连接数。如果连接数突然飙升,多半是应用连接池没释放或配置了不合理的重试机制。还有CLIENT LIST可以列出每个连接的IP和空闲时间,快速定位异常来源。

如果你的部署方式恰好是Docker,还要优先看容器日志。docker logs redis-master 能直接拉出Redis启动时的警告和错误,比如“WARNING: The TCP backlog setting of 511 cannot be enforced”这类提示,虽然不影响启动,但很多时候是后续性能问题的前兆。先看日志、再看INFO、最后慢查询,这个顺序基本能覆盖80%的线上Redis排障场景。

7. 面试必问背后的原理:单线程、持久化与主从复制的判断逻辑

7.1 单线程为什么还快:不要只背“因为内存快”

很多人回答“Redis为什么快”时只说因为基于内存,其实不全面。Redis单线程模型的红利在于:没有多线程切换CPU的开销,没有锁竞争,执行命令时是串行的,天然不需要考虑并发修改问题。而且它用I/O多路复用机制,一个线程可以同时监听大量客户端连接上的读写事件,网络等待不占执行时间。

Redis 6.0开始引入了多线程I/O,把网络数据的读写从主线程拆出去,但命令执行仍然在主线程串行完成。这个设计的核心思想是:把耗时但可以并行的网络读写作并行,把需要原子性的命令执行保持单线程,是典型的时间换稳定。

面试时如果继续追问,可以加上一句话:Redis瓶颈不太可能在CPU单核上,更多在内存大小和网络带宽。所以你在设计缓存时,要尽量控制单个value体积,避免一次请求传输几MB数据,这比纠结要不要多线程更实际。

7.2 RDB和AOF选型:丢了数据别全怪Redis

Redis持久化有两种方案。RDB是快照模式,按配置的时间窗口把内存数据生成二进制快照,恢复速度快;但它会丢最近一次快照之后写入的数据。AOF是追加日志,记录每一条写命令,重启时回放日志恢复数据,但文件会越来越大,恢复比RDB慢。Redis官方后来支持了混合持久化:AOF文件内容前半部分是RDB快照,后半部分是增量命令,兼顾恢复速度和安全性。

给一个可操作的参考:如果Redis只做缓存,丢了能回源,可以不开启AOF,甚至可以把maxmemory设小一点;如果Redis里存了订单号、计数器这类不能丢的数据,必须开AOF,并且设置appendfsync everysec,这样最多丢一秒数据;如果对数据要求极高,再考虑同步落盘,但性能代价明显。没有万能方案,只有你和业务方商量后接受的丢失窗口。

7.3 主从复制和哨兵:想清楚RDB和AOF之后,还要想清楚副本

主从复制是Redis高可用的基础。从节点通过psync协议向主节点发起同步,第一次是全量复制:主节点生成RDB快照发给从节点;之后是部分复制:主节点把增量命令写到复制积压缓冲区,从节点通过偏移量跟上。

哨兵(Sentinel)负责监控主节点,主挂了自动把某个从节点提升为主,并通知客户端新的地址。这套组合是生产环境最常见的底线配置:主从加哨兵,保证不轻易出现“Redis挂了全站跟着挂”。搭建时有一个非常常见的坑:主节点设置了requirepass,从节点除了要配masterauth,还要注意配置文件里bind和protected-mode,否则主从之间互相访问受限,日志里一直出现replication相关的连接拒绝。

另外,主从复制解决的是数据冗余和读扩展,不是写扩展,也不是强一致。极端情况下主从间可能丢数据,所以它对你的意义是“提高可用性”,而不是“保证数据不丢”。用一句话总结我的判断:缓存场景先保可用性,业务数据先保持久化,两者冲突时,你干的是缓存,不是数据库。

如果你正在学Redis,我的建议是别把命令全抄下来,最好是把这篇文章当目录:今天碰到缓存穿透,就把穿透那一段读透,顺手在自己的笔记里补一个真实案例。最近我排一个线上事故,就是因为缓存穿透拖慢了数据库,回头看,这个问题的答案早早就写在“缓存治理”这一节里。真正有价值的是你带着问题回来翻的那一刻,而不是背下来的命令数量。

相关推荐

基于Python+Open CV的手势识别算法设计

伴随着人工智能时代的到来,人机交互的领域也逐渐成为研究的一大方向;其中,手势识别是人机交互领域的一项关键技术,自此手势识别也迎来了一波高潮,近几年无论是在消费领域、电子领域、数码领域、家电领域甚至汽车领域上,都能或多或少的见到手势识别的身影。 手势识别在设计智能高效的人机界面方面具有至关重要的作用, 目前手势识别已应用到手语识别、智能监控、到虚拟现实等各个领域,手势识别的原理都是利用各种传感器(例如红外、摄像头等)对手部的形态进行捕捉并进行建模,形成一个模型信息的序列帧,而后将这些信息序列转换为机器能够识别的相对应指令(例如打开、切换菜单、移动等)来完成控制。 采用Python的集成开发环境Pycharm进行本次课程设计,在Pycharm中进行需要库(模块)的下载,调取电脑摄像头,按帧读取摄像头采集到的头像,形态学处理,图像旋转(由于摄像头采集到的图像是镜像,需要用cv2.flip将摄像头采集到的图像进行处理),选取图片中固定位置作为手势输入,用红线画出手势识别框,基于hsv的肤色检测,进行高斯滤波,找出轮廓,求出图像中手势的凹凸点,手指间角度求取。

努力学习前端的小陈

ROS-CV-ImageConverter:将ROS图像转换为OpenCV(cv :: Mat)类型的图像

ROS-CV图像转换器 依存关系 cv_bridge(ROS软件包)

Willis Wang

计算机视觉图像处理-CV2与图像插值算法

用最近邻插值与双线性插值原理完成图像缩放 最近邻插值,是指将目标图像中的点,对应到源图像中后,找到最相邻的整数点,作为插值后的输。缺点:使用最近邻插值算法处理图像放大时,在图象中可能出现明显的块状效应 双线性插值,在两个方向上做三次线性插值。使用双线性插值算法处理图像放大时,在图象中可能出现马赛克 代码 import cv2 img = cv2.imread(’./xiabang.jpg’, cv2.IMREAD_UNCHANGED) #缩放比例 scale_percent = 0.3 width = int(img.shape[1] * scale_percent) height = int

weixin_38697274

基于水平集CV模型的图像分割(Matlab代码)

基于水平集CV模型的图像分割(Matlab代码),全套代码

小宇QAQ

导向滤波(guide_filter)的python实现

导向滤波(guide_filter)的python实现,可以结合暗通道;理论实现比较好的图像去噪效果。

zachzhan_g
返回顶部
生命的光彩
博客等级 码龄10年 46粉丝 1,442原创