原文链接:http://www.juzicode.com/archives/5075

Hello,大家好,我是桔子菌,今天我们来看些有趣的视觉错觉图。Twitter上有个叫jagarikin的大牛发布了很多这种图片。像下面这张图片里,你是不是看到这些小人在爬楼梯,爬完了又往下跳?

图源:Twitter@jagarikin

要判断是否有运动,当然首先是要找个静止的参照物,我们可以先锁定图片中最大部分的楼梯,其实并没有移动,只是颜色的变化看起来好像在移动。再以楼梯右上角为参考点,它右上方那个小人动作和位置都是静止的,同样的方法找些参考点逐个分析,除了右下角那个小人在原地奔跑,其他小人实际上都是静止的。

上面这张小人图片仔细看还能发现问题所在,像下面这张图片中左右两个彩色的圆,它们的中心位置有发生变化吗?圆的大小有发生变化吗?

图源:Twitter@jagarikin

这张图没有上一张那样有个大的参照物,如果以圆圈中间的箭头作参照物,看起来好像真的有大小变化和位置移动,但是真的如此吗?

直观感觉容易骗人,我们就来做一些“理性”分析,接下来用Python和OpenCV处理看看会是什么结果。

下载下来的原图是gif格式的,gif文件在OpenCV中并不能用imread()直接读取,可以用VedioCapture()把各帧图像提取出来,保存为jpg格式的静态图片:

#juzicode.com VX:桔子code
import os
import time
import cv2
def split_image(fn,path='.\\'):'''从gif中分离图片'''fn_full_path = path+fncap = cv2.VideoCapture(fn_full_path)count_img = 0while True:flag,img = cap.read()if flag is not True:breakcv2.imshow('img',img)cv2.waitKey(10)cv2.imwrite(str(count_img)+'.jpg',img)count_img += 1print('count_img=',count_img)if name == "__main__":img_fn = '1.gif'split_image(img_fn)

好家伙,这一个gif图片里面居然有199帧图片。

接下来我们就来分析这些图片,首先是imread()读取图片:

path = '.\\'
img_files = [f for f in os.listdir(path) if '.jpg' in f]
for  file in img_files:img_dest = cv2.imread(path+file)show_img('img_dest VX:juzicode/juzicode.com',img_dest,is_show=dbg_is_show,wait_time=100)

然后在RGB彩色空间里提取R、G、B分量二值化之后效果并不是很好。

我们知道彩色图像除了用RGB彩色空间也可以用HSV彩色空间表示,RGB转换为HSV后提取H、S、V分量:

img_hsv = cv2.cvtColor(img_dest, cv2.COLOR_BGR2HSV)#RGB转换为hsv
show_img("hsv", img_hsv,wait_time=100)
img_h, img_s, img_v = cv2.split(img_hsv) #分离hsv各分量
show_img('img_h',img_h,is_show=dbg_is_show,wait_time=200)
show_img('img_s',img_s,is_show=dbg_is_show,wait_time=100)
show_img('img_v',img_v,is_show=dbg_is_show,wait_time=200)  

下面是RGB彩色空间和HSV彩色空间对比的效果:

将H、S、V分量分别显示出来,发现下图右下角的S分量对比度极高,可以用来做二值化处理:

在S分量上进行二值化:

thresh_bin,img_bin= cv2.threshold(img_s,30,255,cv2.THRESH_BINARY)
print('thresh_bin',thresh_bin )
show_img('img_bin',img_bin,wait_time=100,is_show=dbg_is_show)  

二值化后的图像效果不错,前景背景区分非常明显,下图右侧是S分量图像,左侧是S分量二值化后的图像:

接下来就是在二值化图像中找圆心位置、计算圆的半径,等价于计算内外圆外框的起始位置和宽高,如果内外圆外框的起始位置和宽高没有变化或者变化极小,就能说明圆圈并没有移动位置、大小也没有发生变化。

res = cv2.findContours(img_bin,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
contours=res[0]
print ('len(contours):',len(contours))
for i in range(0,len(contours)): x, y, w, h = cv2.boundingRect(contours[i])#提取起点、宽高print(i,len(contours[i]))if len(contours[i])<80:continue #去除噪声text='x,y=(%d,%d) w,h=(%d,%d)'%(x, y, w, h)if x< 150: #这里只显示左侧圆的内外圆起始位置和宽高cv2.putText(img_dest, text, (x,y-10 ), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)  cv2.rectangle(img_dest, (x,y), (x+w,y+h), (0,0,255), 3)show_img("img_dest_rect", img_dest,wait_time=100) 

下图中右上角的子图显示的是左侧内外圆的外框起始位置(x,y)和宽高(w,h):

通过采集内外圆的起始位置(x,y)和宽高(w,h)4个参数,动态对比了199张图像,波动都只在3个像素以内:

如果将起始位置(x,y)和宽高(w,h)用matplotlib绘图,左右圆的内外圆组成的4个框图的起点位置(x,y)都聚集在4个角落位置,4个框图的宽高(w,h)都聚集在对角2个位置,对应了内圆和外圆的大小。

通过将原图中圆环的内外圆位置和大小经过数值化提取后,再比较定量的数值数据,可以得出明确的结论,原图中的圆环并没有挪动位置、改变大小。

现在有了定量的分析,你还认为原图中的2个圆圈位置和大小在发生变化吗?实际上原图中圆圈内的小箭头才是“罪魁祸首”,是它们在诱导你作出错误的判断。

聪明的你看到下面这个正方体是在转动的吗?

图源:Twitter@jagarikin

来看看怎么用OpenCV解构jagarikin的视觉错觉图相关推荐

  1. 2021地理设计组一等奖:融合短视频和深度学习的城市空间意象解构与分析

    作品简介 一.应用背景与目标 城市是自然.构筑物及人构成的复杂动态综合体.城市空间意象是人们感受到的城市空间表达,也是人们对城市的直接或间接的经验性的空间认识.解构城市空间意象[1]作为城市空间认知研 ...

  2. 如何充分利用JavaScript(ES6)中的解构功能

    by Joanna Gaudyn 乔安娜·高登(Joanna Gaudyn) Destructuring was a new addition to ES6. It took inspiration ...

  3. ES6语法~解构赋值、箭头函数、class类继承及属性方法、map、set、symbol、rest、new.target、 Object.entries......

    2015年6月17日 ECMAScript 6发布正式版本 前面介绍基本语法,  后面为class用法及属性方法.set.symbol.rest等语法. 一.基本语法:  1.         定义变 ...

  4. (6)解构赋值的用途

    解构赋值的用途 1.交换变量的值 var a = 100; var b = 200; var t; t = a; a = b; b = t; //解构赋值的写法完成[ES6交换变量的值] var x ...

  5. 【ES6】变量的解构赋值

    [ES6]变量的解构赋值 一.什么叫解构赋值? 二.解构赋值有哪些分类?写法? 1)对数组的解构赋值 2)对对象的解构赋值 3)对字符串的解构赋值 4)对数值和布尔值的解构赋值 5)对函数参数的解构赋 ...

  6. 用深度学习模型,解构并重构人类思维

    来源:人机与认知实验室 概要:人类的知识,往往由事实 fact 和规则 rule 组成,而且人类习惯于用简练的词汇,来表达事实和规则.所以,维特根斯坦认为,人类思维受制于语言结构,语言的界限决定思维的 ...

  7. 业务代码解构利器--SWAK

    简介 业务的不断发展.商品类型的不断增多.不断添加的业务需求使得闲鱼的代码出现"bad smell"--平台代码和业务代码耦合严重难以分离:业务和业务之间代码交织缺少拆解.这也是行 ...

  8. ECMAScript6变量的解构赋值

    ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring) ###数组的解构赋值 //ES5 //var a = 1; //var b = 2; //va ...

  9. ES6数组的解构赋值( 中)

    数组的解构赋值的用法有以下几情况要注意: 1.结构赋值可以嵌套的 数组的解构赋值的用法有以下几情况要注意:1.结构赋值可以嵌套的 var [ a,b,[ c1,c2 ] ] = [ 1,2,[ 3.1 ...

最新文章

  1. cdr怎样把一张图片随意变形_PS手记|移动工具的使用与画布的变形
  2. hihocoder编程练习赛75
  3. 1.15.Flink state(状态)管理与恢复、什么是state、Keyed State、Operator State、状态容错(生成快照,恢复快照),checkPoint简介,重启策略等
  4. PHP artisan auth,Php artisan make:auth命令未定义
  5. Go语言 命令行解析(一)
  6. 位带操作全解释,个人觉得不错就转过来理解下
  7. win下修改anaconda的jupyter notebook默认打开路径
  8. 关于吾爱(52)破解网注册时临时安全验证码以及填完信息没有确认或提交按钮的问题
  9. 中小企业生产信息化:私有系统还是云方案?
  10. html浏览xsd,那点你不知道的XHtml(Xml+Html)语法知识(DTD、XSD)
  11. 北大计算机系赖陆程,北大计算机系一年级学生彭某从五楼阳台上跳下。彭某曾是一个相当聪明...
  12. CSS统计数据记录数量
  13. Vue3.x-bate + Antd2.x 项目搭建报错
  14. 华为关闭系统更新EMUI9.0禁止更新mate10降级EMUI9
  15. rabbitmq reply-code=404, reply-text=NOT_FOUND
  16. Mysql内查询时报错,错误代码: 1146
  17. android hdmi 监听,对于HDMI设备连接状态的监听
  18. 求职中的平常心——Leo网上答疑48
  19. openCV-python 入门笔记
  20. 利用Gitlab进行代码的协作开发

热门文章

  1. Python和二进制(1)
  2. 软件加密系统Themida应用程序保护指南(九):通过命令行进行保护
  3. 5个最适合开发人员的协作平台
  4. 树莓派 python 蜂鸣器_红外感应模块+蜂鸣器实现简易报警
  5. 以色列初创企业Skyline AI获300万美元种子融资,红杉资本领投
  6. 杜克大学计算机科学,杜克大学计算机科学硕士排名第29(2020年TFE Times排名)
  7. C++基于OpenCV实现实时监控和运动检测记录
  8. HSIC转USB国产芯片 宸芯科技模块调试案例分享
  9. python画函数图像网格_使用opencv python在图像上绘制网格线
  10. 大学英语六级词汇(笔记)