Leap motion 擴增實境
利用 OpenCV 校正攝影機以及 Leap Motion Sensor 的位置,再利用 Three.js 來達成擴增實境的效果。
這是試玩的結果(還是跟 IPython notebook 一起探索),所以並沒有以最佳效果為目標。實際上 leap motion sensor 可以放在比較好的位置。
稍早拿來和 google hangout api 配合的效果。
原理上不難,只是中間要解決一堆技術上的小麻煩。
import spynner
import os, sys
from PyQt4.QtWebKit import QWebSettings # 用來設定 QtWebKit
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest # 控制 browser 的網路連線
from PyQt4.QtCore import QUrl # Qt 的 Url 類別
# 下面是新增的兩個 module
import urllib2
from multiprocessing.pool import ThreadPool
# 下面是 IPython 相關
from IPython.display import display, Image
from IPython.html.widgets import ImageWidget, IntProgressWidget
# 建立瀏覽器
browser = spynner.Browser(debug_level=spynner.ERROR, debug_stream=sys.stderr)
# 建立一個 webview
browser.create_webview()
settings = browser.webview.settings()
# settings.setAttribute(QWebSettings.AutoLoadImages, False)
settings.setAttribute(QWebSettings.JavaEnabled, False) # 不需要 Java
settings.setAttribute(QWebSettings.DnsPrefetchEnabled, True) # 試著節省 Dns 花的時間
settings.setAttribute(QWebSettings.PrivateBrowsingEnabled, True) # 不需要瀏覽紀錄或者 cookie
# 建立一個空的 url
BLANK_REQUEST = QNetworkRequest(QUrl())
# 建立一個空的圖片 url
DUMMY_IMG_REQUEST = QNetworkRequest(QUrl("data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs="))
# 客製化的 NetworkAccessManager
class EightComicNetworkAccessManager(QNetworkAccessManager):
# 只需要取代 createRequest 這個 method 即可
def createRequest(self, op, request, device=None):
url = str(request.url().toString()) # 參數很多,但只取 url 就夠用
if 'comic' not in url[:20]:
# 用很醜的方式來判斷非 8comic 網站的 url
# 用空的 url 取代原本的 url
return QNetworkAccessManager.createRequest(self, self.GetOperation, BLANK_REQUEST)
elif not url.endswith('js') and not url.endswith('css') and '.html' not in url:
# 凡是 .js .css .html 之外的,都用空的圖片 url 取代原本的 url
return QNetworkAccessManager.createRequest(self, self.GetOperation, DUMMY_IMG_REQUEST)
else:
# 傳回原本的 url
return QNetworkAccessManager.createRequest(self, op, request, device)
# 設定 browser 的 NetworkAccessManager
browser.webpage.setNetworkAccessManager(EightComicNetworkAccessManager())
browser.show()
# 漫畫的網頁
base_url = 'http://new.comicvip.com/show/cool-5614.html?ch='
# 要下載第一本
book_no = 1
# 取得總頁數
browser.load(base_url+str(book_no))
total_pages = browser.runjs('ps').toInt()[0]
# 建立 Image Widget 用來顯示圖片預覽
img = ImageWidget()
img.set_css("height", 300) # 讓圖片不要太大
# 顯示下載進度的 Progress bar
html_progress = IntProgressWidget(min=1, value=1, max=total_pages)
img_progress = IntProgressWidget(min=1, value=1, max=total_pages)
# 顯示 Widget
display(html_progress)
display(img_progress)
display(img)
# 建立一個下載目錄
dir_name = "download/{:02d}".format(book_no)
if not os.path.exists(dir_name):
os.makedirs(dir_name)
print "Download to {}/{}".format(os.getcwd(), dir_name)
sys.stdout.flush()
# 建立 ThreadPool, 5 條 thread
pool = ThreadPool(5)
# 開始下載
downloaded_images = 0
for page in range(1, total_pages+1):
# 取得 image url
browser.load("{}{}-{}".format(base_url, book_no, page))
img_url = str(browser.runjs('document.getElementById("TheImg").getAttribute("src")').toString())
# 將下載圖片的工作包成 save_img,推進 pool 裡
def save_img(img_url, page):
global downloaded_images
fn = "{}/{:03d}.jpg".format(dir_name, page)
data = urllib2.urlopen(img_url).read()
with open(fn, "wb") as f:
f.write(data)
# 更新 widget 的狀態
downloaded_images += 1
img_progress.description = "img: %d/%d"%(downloaded_images, total_pages)
img_progress.value = downloaded_images
img.value = Image(filename=fn).data
pool.apply_async(save_img, (img_url, page))
# 更新 Widget 的狀態
html_progress.description = "html: %d/%d"%(page, total_pages)
html_progress.value = page
# 等待所有任務結束
pool.close()
pool.join()
import spynner
import os, sys
from PyQt4.QtWebKit import QWebSettings # 用來設定 QtWebKit
from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest # 控制 browser 的網路連線
from PyQt4.QtCore import QUrl # Qt 的 Url 類別
# 下面這行是 IPython 相關
from IPython.display import display, Image
from IPython.html.widgets import ImageWidget, IntProgressWidget
# 建立瀏覽器
browser = spynner.Browser(debug_level=spynner.ERROR, debug_stream=sys.stderr)
# 建立一個 webview
# 我們不設定 AutoLoadImages=False, 但增加一些其他設定
# 這裡並不是重點,但適合我們的應用
browser.create_webview()
settings = browser.webview.settings()
# settings.setAttribute(QWebSettings.AutoLoadImages, False)
settings.setAttribute(QWebSettings.JavaEnabled, False) # 不需要 Java
settings.setAttribute(QWebSettings.DnsPrefetchEnabled, True) # 試著節省 Dns 花的時間
settings.setAttribute(QWebSettings.PrivateBrowsingEnabled, True) # 不需要瀏覽紀錄
# 建立一個空的 url
BLANK_REQUEST = QNetworkRequest(QUrl())
# 建立一個空的圖片 url
DUMMY_IMG_REQUEST = QNetworkRequest(QUrl("data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs="))
# 因為只需要用一次,可以取個又臭又長的名字
class EightComicNetworkAccessManager(QNetworkAccessManager):
# 只需要取代 createRequest 這個 method 即可
def createRequest(self, op, request, device=None):
url = str(request.url().toString()) # 參數很多,但只取 url 就夠用
if 'comic' not in url[:20]:
# 用很醜的方式來判斷非 8comic 網站的 url
# 用空的 url 取代原本的 url
return QNetworkAccessManager.createRequest(self, self.GetOperation, BLANK_REQUEST)
elif not url.endswith('js') and not url.endswith('css') and '.html' not in url:
# 凡是 .js .css .html 之外的,都用空的圖片 url 取代原本的 url
return QNetworkAccessManager.createRequest(self, self.GetOperation, DUMMY_IMG_REQUEST)
else:
# 傳回原本的 url
return QNetworkAccessManager.createRequest(self, op, request, device)
# 設定 browser 的 NetworkAccessManager
browser.webpage.setNetworkAccessManager(EightComicNetworkAccessManager())
# 漫畫的網頁
base_url = 'http://new.comicvip.com/show/cool-5614.html?ch='
# 顯示瀏覽器,確認 browser 內容乾淨清爽
browser.show()
# 要下載第一本
book_no = 1
# 取得總頁數
browser.load(base_url+str(book_no))
total_pages = browser.runjs('ps').toInt()[0]
# 建立 Image Widget 用來顯示圖片預覽
img = ImageWidget()
img.set_css("height", 300) # 讓圖片不要太大
# 顯示下載進度的 Progress bar
progress = IntProgressWidget(min=1, value=1, max=total_pages)
# 顯示 Widget
display(progress)
display(img)
# 建立一個下載目錄
dir_name = "download/{:02d}".format(book_no)
if not os.path.exists(dir_name):
os.makedirs(dir_name)
print "Download to {}/{}".format(os.getcwd(), dir_name)
sys.stdout.flush()
# 開始下載
for page in range(1, total_pages+1):
# 取得 image url
browser.load("{}{}-{}".format(base_url, book_no, page))
img_url = str(browser.runjs('document.getElementById("TheImg").getAttribute("src")').toString())
# 下載圖片
fn = "{}/{:03d}.jpg".format(dir_name, page)
with open(fn, "wb") as f:
browser.download(img_url, outfd=f)
# 更新 Widget 的狀態
progress.description = "%d/%d"%(page, total_pages)
progress.value = page
img.value = Image(filename=fn).data
import spynner
import os, sys
from PyQt4.QtWebKit import QWebSettings # 用來設定 QtWebKit
# 下面是 IPython 相關
from IPython.display import display, Image
from IPython.html.widgets import ImageWidget, IntProgressWidget
base_url = 'http://new.comicvip.com/show/cool-5614.html?ch='
# 建立瀏覽器
browser = spynner.Browser(debug_level=spynner.ERROR, debug_stream=sys.stderr)
# 建立一個 webview,並且設定不要自動載入圖片
browser.create_webview()
settings = browser.webview.settings()
settings.setAttribute(QWebSettings.AutoLoadImages, False)
# 要下載第一本
book_no = 1
# 取得總頁數
browser.load(base_url+str(book_no))
total_pages = browser.runjs('ps').toInt()[0]
# 建立 Image Widget 用來顯示圖片預覽
img = ImageWidget()
img.set_css("height", 300) # 讓圖片不要太大
# 顯示下載進度的 Progress bar
progress = IntProgressWidget(min=1, value=1, max=total_pages)
# 顯示之前建立的 Widget
display(progress)
display(img)
# 建立一個下載目錄
dir_name = "download/{:02d}".format(book_no)
if not os.path.exists(dir_name):
os.makedirs(dir_name)
print "Download to {}/{}".format(os.getcwd(), dir_name)
sys.stdout.flush()
# 開始下載
for page in range(1, total_pages+1):
# 取得 image url
browser.load("{}{}-{}".format(base_url, book_no, page))
img_url = str(browser.runjs('document.getElementById("TheImg").getAttribute("src")').toString())
# 下載圖片
fn = "{}/{:03d}.jpg".format(dir_name, page)
with open(fn, "wb") as f:
browser.download(img_url, outfd=f)
# 更新 Widget 的狀態
progress.description = "%d/%d"%(page, total_pages)
progress.value = page
img.value = Image(filename=fn).data
easy_install -N spynner
!easy_install spynner
(win8 可用搜尋找到 IPython)# This is for windows
# on linux, simply sudo easy_install spynner in command line
!easy_install spynner
# restart the kernel
import spynner
import os, sys
# 下面這行是 IPython 相關
from IPython.display import display, Image
browser = spynner.Browser(debug_level=spynner.ERROR, debug_stream=sys.stderr)
browser.show() # 告訴 browser,要它之後不要隱身
# 為了避免法律上的疑慮,這裡你要自己找到適當的 url,把 ???? 換掉
base_url = 'http://???.com/show/????-????.html?ch='
browser.load( base_url+'1')
browser.load_jquery(True) # spynner 內建有 jquery,用這個 method 載入,比較方便。
img_url = str(browser.runjs('$("#TheImg").attr("src")').toString())
print img_url
# 當然不用 jquery 也可以
img_url = str(browser.runjs('document.getElementById("TheImg").getAttribute("src")').toString())
print img_url
# 直接顯示 url 看看
display(Image(url=img_url, width=200))
# 先用 browser 抓下圖檔內容, 然後顯示
display(Image(data=browser.download(img_url), width=200))
total_pages = browser.runjs('ps').toInt()[0]
print total_pages
book_no = 1
for page in range(1, total_pages+1):
browser.load("{}{}-{}".format(base_url, book_no, page))
img_url = str(browser.runjs('document.getElementById("TheImg").getAttribute("src")').toString())
print page, img_url
display(Image(url=img_url, width=100))
continue
# 上面只是顯示每一頁的圖片
# 如果你現在就想真的抓檔案下來, 把上面那個 continue 註解掉
with open("{}-{}.jpg".format(book_no, page), "wb") as f:
browser.download(img_url, outfd=f)
print "File saved in", os.getcwd()
![]() |
Toomore 的 GRS 演講錄影算是我的「動機」,你可以看看這個動機能不能說服你 |
![]() |
原來文字完全糊成一團 |
![]() | ||
這是一開使用來試驗的對象,原本直接方差,效果還不錯。 |
![]() |
海總理的演講,錄影品質也不行,這是第二個處理的影片。 |
![]() |
![]() |
海總理的影片,處理效果也不錯,不過第一章投影片似乎字體大小有改過,所以抓不到 |
![]() |
Cheng-Lung Sung 的影片又是令一個問題,跟其他影片不一樣,不事由投影機訊號直接錄的。 |
![]() |
原本想利用 OpenCV 的 Perspective Transformation 來修改互動工具,但沒想到原本的工具看起來堪用。 |
![]() |
Andy 的影片原始畫質就還可以,不過利用投影片,還是可以讓畫質由還可以變成完美。 |
![]() |
但一來原本畫質就還可以,二來投影片有一些動畫,所以閥值設定的比較高。 |
![]() |
駱勁成關於立院投票指南的演講 |
![]() |
跟其他有些不同的地方在於,替代的投影片大小放大為全螢幕。 |
![]() |
最開始其實是打算用 Feature Matching 的方式,但因為一開始實驗的對象是最模糊的兩個演講,發現不靈。所以放棄這招。不過對於比較清楚的影片,其實 feature matching 看起來效果還不錯。 |
Copyright ©
松鼠博士的魔法眼鏡 | Powered by Blogger
Design by SimpleWpThemes | Blogger Theme by NewBloggerThemes.com