白云苍狗看复鹿 冥鸿相助见神龙

金庸先生在《鹿鼎记》里讲到,韦小宝因机缘巧合拜了诸多高明师傅,但只对铁剑门绝技“神行百变”大感兴趣,学得津津有味。虽说“神行”差得远,“百变”两字却和他天性很是相近。小宝虽然是市井出身,可仗着圆滑的处事之道和主角光环,做了朝廷的公爵、天地会青木堂主、神龙教白龙使,典故成语说得鲁鱼亥豕,做事倒是很照顾朋友。出生入死盗得八部四十二章经,把里面的碎羊皮拼凑成图,按图到了鹿鼎山,却忽然害怕起来,只盼找个甚麽借口,离得越远越好。一方面是胆怯,一方面是怕挖了龙脉坏了朋友小玄子康熙的性命。

百余年后,我得到DragonBoard™410c的板子,想来想去,决定做个给拼板自动打分的游戏。拼版就是这个:

这个东西叫四巧板,是一种类似七巧板的传统智力玩具。包括大小不同的直角梯形各一块,等腰直角三角形一块,凹五边形一块。这几个多边形的内角除了有直角外,还有45º、135º和270º的角,每个角度都是45度的倍数。四块板子间有着非常默契的关系,可以把整个四巧板看成由四个相同的等腰直角三角形和相对应的直角梯形组成。由于四块板子之间相互呼应的科学合理的结构,所以可以排列组合出成百种图形,训练和提高玩者的图形思维和智力。

应用的组件结构和操作流程是这样的:

回到DragonBoard,拿到板子之前,自然是做了不少作业:

快递送来板子那天,我小心翼翼的打开箱子:

拆开一看。纳尼?少东西!

少的是电源到板上电源插孔的转接头。经过和群里童鞋的讨论,得知了准确的型号,于是果断下单。然而身在帝都的我赶上了全世界的一件大事,于是快递就悠闲地在祖国大好河山旅游了一下下,时间比我年假都长。终于,它到了。

于是就上电,完全没有用烧好的micro sd,直接就起来了:

桌面是lxde,有评测说是最快的精简桌面。我更关心安装的组件有哪些,因为我要用的工作语言是python,原意是大蟒,用来配DragonBoard很搭哦。

当然,既然要做到能给拼板自动打分,就要用到视频视觉的库。说起来,既然用高通的芯,FastCV是最好的选择。但是鉴于时间有限,并且我现在只会使一种锤子,所以很不好意思的说,用的库是大家耳熟能详的——

先检查,gpio支持,不用管内核了,usb摄像头也认:

空间也够:

接下来,开始各种装:

有了opencv,最大的库算是更新完了,以后再有缺的,随时apt-get之。

此时可以用这个小程序验证opencv和摄像头的工作是否正常:

import cv2
cap = cv2.VideoCapture(0)
ret,frame=cap.read()
cv2.imshow('img',frame)
cv2.waitKey(0)
cap.release()
cv2.destroyAllWindows()

补充一句,python环境版本是2.7.9。

注意,此处没有华丽丽的分割线,但是下面开始就是干货了……

玩过树莓派的同学一定听说过RPi.GPIO,可惜那不是纯py的,要移植。考虑到我要用到的也就是个按钮,于是决定用python直接操作文件的方式来实现:

# -*- coding: utf-8 -*-

class SimpleGPIO():

def __init__(self,gpio=None):

self._base_path= "/sys/class/gpio/"

self._gpio = gpio

#self._direction = None

#self._edge = None

#self._last_value = None

def setGPIO(self,gpio):

self._gpio = gpio

def getGPIO(self):

return self._gpio

def _writeFile(self,file_name,value):

fo = open(file_name, "w")

fo.write(value)

fo.close()

def _readFile(self,file_name):

fo = open(file_name, "r")

value = fo.read(7)

fo.close()

return value

def export(self):

self._writeFile( self._base_path+"export" , str(self._gpio) )

def unexport(self):

self._writeFile( self._base_path+"unexport" , str(self._gpio) )

#in或out。写入low或high

def _setDirection(self,direction):

self._writeFile(  self._base_path+"gpio"+str(self._gpio)+"/direction" , direction)

def getDirection(self):

return self._readFile( self._base_path+"gpio"+str(self._gpio)+"/direction")

#”none”, “rising”, “falling”,”both”

def _setEdge(self,edge):

self._writeFile(  self._base_path+"gpio"+str(self._gpio)+"/edge" , edge)

def getEdge(self):

return self._readFile( self._base_path+"gpio"+str(self._gpio)+"/edge" )

#setup gpio

def setGPIOoutHIGH(self):

self._setDirection("high")

def setGPIOoutLOW(self):

self._setDirection("out")#self._setDirection("low")

def setGPIOin(self):

self._setDirection("in")

self._setEdge( "none")

def setGPIOinRaising(self):

self._setDirection("in")

self._setEdge("rising")

def setGPIOinFalling(self):

self._setDirection("in")

self._setEdge("falling")

def setGPIOinBoth(self):

self._setDirection("in")

self._setEdge("both")

# 1 , 0

def _setValue(self,value):

self._writeFile( self._base_path+"gpio"+str(self._gpio)+"/value" , value )

def setValueHigh(self):

self._setValue(self,'1')

def setValueLow(self):

self._setValue(self,'0')

def getValue(self):

return self._readFile( self._base_path+"gpio"+str(self._gpio)+"/value" )

下一个问题是界面用什么做。Opencv提供的窗口虽然刷新速度比较快,但是我这个水平,界面元素全靠画,太费劲。决定采用python广谱抗菌随身携带家居旅行必备的——TKinter。

Tkinter最大的优势是历史悠久,装了python就能支持;劣势也有不少,不过这个demo级的应用对这些缺点还真不太敏感。

先一条,有点想一下界面元素:我想用一个满屏的窗口显示,在屏幕顶端是一行提示,很窄的,有点windows或mac os窗口标题的那种意思。下面的屏幕分成左右两部分,左边是网上下载的题目,右边是定时刷新的摄像头快照。如果按了评分键,会在快照上层显示出一个评分。那么这样一个窗口需要如何实现呢?

class GameApp(object):

def __init__(self, master, **kwargs):

self.root = master

self.frame = tk.Frame(self.root,bg='red')

self.frame.pack(fill=tk.BOTH)

self.statsbar = tk.Label(self.frame, text=TXT_TIPS,bg='black',fg = 'orange',font=('system', 16, "bold"),compound = tk.CENTER)

self.statsbar.pack(fill=tk.X)

win_screen_w = self.root.winfo_screenwidth()

win_screen_h = self.root.winfo_screenheight()

self.lbl_que=tk.Label(self.frame, text='',bg='black', bitmap="info"    ,width = win_screen_w/2,compound = tk.CENTER, image=img_que)

self.lbl_que.pack(side=tk.LEFT,fill=tk.Y)

self.lbl_cap=tk.Label(self.frame, text='',bg='white', bitmap="question",width = win_screen_w/2,compound = tk.CENTER, image=img_cap, height=win_screen_h,font=('system', 40, "bold"),fg='red' )

self.lbl_cap.pack(fill=tk.BOTH,side=tk.RIGHT)

self.root.bind("<Escape>", self.exit_application)

self.root.bind("<KeyPress>", self.on_key_press)

self.refreshCapture()

def do_fullscreen(self):

#self.root.attributes("-fullscreen", True)

return

def exit_application(self, event=None):

self.root.destroy()

return

def on_key_press(self, event=None):

print (event.char,event.keysym)

return

有了界面,我们可以把重点放到主要逻辑上了。

首先是抓图,使用cv2.VideoCapture(0)可以获得摄像头,再调用摄像头的read()方法就可获得一帧,需要注意的是opencv的图像颜色顺序是BGR,如果交给tk显示,需要调整成RGB。

global img_cap,img_cv_cap

cap = cv2.VideoCapture(0)

ret, img = cap.read()

cap.release()

img_cv_cap = img.copy()

#Rearrang the color channel

im = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGBA))

img_cap = ImageTk.PhotoImage(image=im)

self.lbl_cap.configure(image=img_cap)

下一个关键点是定时抓图,这个是靠Tk的.after()方法实现。after()方法有两个参数,第一个是sleep的毫秒数,第二个是响应过程,比如本demo实现定时拍照刷新就是用这句实现的:

self.root.after(100,self.refreshCapture)

最后一个关键问题是如何比较拼出的图形与标准图形是否相似,这里用到了cv2.matchShapes方法,返回的值越小说明相似程度越大。本来在做形状匹配之前,需要对照片进行转换色彩空间、按颜色准备模板、抠图这些操作。但是由于我用的是淡黄色拼版,而且是放在黑色背景上做自动识别,因此省了不少力气,只需要转换成灰度图即可。

def calc_diff(self,img1,img2,th=127):

img1b=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)

img2b=cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)

ret, thresh1 = cv2.threshold(img1b, th, 255,0)

ret, thresh2 = cv2.threshold(img2b, th, 255,0)

ret,contours1,hierarchy = cv2.findContours(thresh1,2,1)

ret,contours2,hierarchy = cv2.findContours(thresh2,2,1)

if ( len(contours1)<=0 or len(contours2)<=0 ):

return 100

cnt1 = contours1[0]

cnt2 = contours2[0]

ret = cv2.matchShapes(cnt1,cnt2,1,0.0)

return ret

如果环境昏暗,背景和拼版的反差会变小,因此阈值th不能取得太大,大约80就可以了。80是在天刚黑的室内环境实验出来的,如果80都分辨不出来,那也太暗了,可以忽略这种情况。

白云苍狗看复鹿 冥鸿相助见神龙相关推荐

  1. 我们专访了神龙云服务器产品负责人,看懂阿里云发布的“神龙”到底“神”在哪里

    摘要: 2017年杭州云栖大会上,阿里云副总裁李津发布了一款被称为神龙的云服务器产品,神龙刚刚亮相,就在业界引发一阵惊呼,小编为了帮助大家看懂神龙,在云栖大会期间,专访了神龙的产品负责人张献涛,看看他 ...

  2. 我们专访了神龙云服务器产品负责人,看懂阿里云发布的“神龙”到底“神”在哪里...

    2017年杭州云栖大会上,阿里云副总裁李津发布了一款被称为神龙的云服务器产品,神龙刚刚亮相,就在业界引发一阵惊呼,小编为了帮助大家看懂神龙,在云栖大会期间,专访了神龙的产品负责人张献涛,看看他将给大家 ...

  3. 华为预装国产系统UOS开箱实录,mac看了沉默,Windows见了落泪...(附镜像下载)...

    下载地址 官方: https://www.chinauos.com/cooperative/download?nav=download 官方下载需要填写个人身份证号码和真实姓名, 2至3天后审核才可使 ...

  4. linux命令行可以看图片吗,活久见!Linux命令行居然也可以用来查看图像?

    在 Linux 中有很多 GUI 应用程序可以查看图像,但是这对经常使用命令行来工作的人可能会觉得很繁琐.今天要介绍的是 3 个实用的 CLI 图像查看器来在终端上查看图像,让那些使用 CLI 的朋友 ...

  5. 洪荒开局鸿蒙绑定系统,洪荒开局绑定鸿钧

    元辰的到来,鸿钧自然不可能拖延下去,几乎就在元辰坐下的瞬间,鸿钧也就出现了. "见过元辰道友." 鸿钧打了一个招呼. 元辰从气息的感受上来说,鸿钧的气息变得更加缥缈了. 距离合道越 ...

  6. 《谈学单片机有前途还是嵌入式系统有前途》一文吴坚鸿回复整理

    六月初吴坚鸿发表了<吴坚鸿谈学单片机有前途还是嵌入式系统有前途>一文.后被andy1989转发至博客中,在发烧友中引起了非常大的反响.对于论坛上非常多发烧友的评论.吴坚鸿一一作了答复.吴先 ...

  7. 论文解读 | 微信看一看实时Look-alike推荐算法

    作者丨gongyouliu 编辑丨lily 来源 | 授权转载自大数据与人工智能(ID:ai-big-data) 微信看一看的精选文章推荐(见下面图1)大家应该都用过,微信团队在今年发表了一篇文章来专 ...

  8. 达摩院送你100万,请坚持“看月亮”

    首批青橙奖获奖者合影 30年前,随便走进一间中国的小学教室,问其中埋头苦读的孩子,长大以后要做什么? "做个科学家!" 梦想改变世界的小娃娃眼神透亮,声音也透亮. 但少有人能够真正 ...

  9. 从 VMWare 到阿里神龙,虚拟化技术 40 年演进史

    [CSDN 编者按]这几年,越来越多的企业把业务搬到云上来,阿里云顺势推出一个既兼具物理机的性能同时又能提供虚拟机体验的产品--神龙.这款服务器的架构是怎样的?有何特别之处?在「CSDN 在线峰会 - ...

最新文章

  1. 安装envi出现cannot find lincese_Ubuntu 16.04 安装 CUDA10.1 (解决循环登陆的问题)
  2. 【kudu pk parquet】TPC-H Query2对比解析
  3. 一蹴而就的解释是什么_健身会让我们成为什么样的人?
  4. UA MATH566 统计理论 Cramer-Rao不等式与Delta方法的联系
  5. java实现鸭子类型,Golang的interface及duck typing鸭子类型
  6. MySQL 视图简析
  7. git可视化工具—GitKraken
  8. 扒一扒9.3阅兵直播如何采用虚拟现实技术
  9. 数据库的常用操作语句
  10. 简单计算器代码(含加减乘除取余5个操作)
  11. 凿音下载 1.26 安卓版
  12. dcdc 国产 电源芯片电路方案 选型小体积大功率高性价比推荐 不定期更新中..
  13. 毕业设计必备案例:Python开发桌面程序——各种版本学生信息管理系统
  14. 免费天气API,免费天气接口,天气预报
  15. sFlow监控OVS使用测试
  16. python内置函数返回元素个数_Python内置函数
  17. WWW2021论文速递:细粒度城市流量预测
  18. 中兴力维动环监控_中兴力维传统动环监控系统解决方案
  19. 用JavaScript去找出一个数组里的所有素数(质数)
  20. Sync BN:Synchronized BN

热门文章

  1. web中的清除浮动方法
  2. html清除js设置的浮动,css 怎么清除浮动
  3. CMMI特定目标(SG)和特定实践(SP)汇总
  4. 【网红流水线车间】“制造”李佳琦们的神秘组织,到底是怎么让网红火起来的?...
  5. memcache set操作详解
  6. iOS Background Fetch 后台应用程序刷新的使用
  7. iphone两个备份合并_看完这篇干货,再备份iPhone数据
  8. Splatter Painting
  9. mac系统docker发布镜像报错:错误the user name or passphrase you entered is not correct解决
  10. windows10在哪修改内网网段或者固定IP