找到思聰王
IG 奪冠啦!王老闆火啦!連王老闆吃熱狗都吃的如此銷魂,那我們當然要來在人群中找到他呢!
看到一個美術生的作品,如何 3 秒內找到思聰王。
我找了好久啊,這幅圖畫的真是魔性,看得眼睛都花了,浪費了我寶貴的上班時間。不得不承認,我,作為一個工科生,3 秒鐘是找不到了。但是,我的電腦可以呀!
連美術生都出動調侃王思聰了,工科生怎麼能坐以待斃!那我就趁著上班,來做一個自動找王思聰的實現吧。
既然在上班,就要用一種比較專業的方式來展開我的工作。
專案目標: 在一群鴨子中找到 吃熱狗的 王思聰
專案成果:0.3 秒內找到
專案技術路線:
- 獲得鴨子同等大小的王思聰;
- 在原圖全域性搜尋,匹配王思聰所在的位置;
- 在王思聰周圍畫個紅框;
- 檢視計算機速度;
專案具體實現:
影象處理,作為計算機演算法中十分大的一類,現成的程式碼庫中有一個非常適合用來做
1.獲得鴨子同等大小的王思聰 —— resize(OpenCV)
這個部分主要是資料的預處理,說得很專業,其實就是用電腦自帶的截圖工具,擷取一個小鴨子,他的大小大約為 36*36。我們就相應地把王思聰 resize 到和小鴨子同等大小,這裡採用了插值 inter_cubic 的方式來進行重取樣。
王思聰的圖來自 那位可愛的美術生。
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Wed Nov7 11:42:02 2018 @author: aaron """ import cv2 template = cv2.imread('wangsicong.png') template = cv2.resize(template, (40, 40), interpolation=cv2.INTER_CUBIC)複製程式碼
2.在原圖全域性搜尋,匹配王思聰所在的位置 —— matchTemplate (opencv)
OpenCV 作為一個比較全能的影象處理庫,能夠提供較為許多影象處理的基礎,比如邊緣監測函式可以直接用於監測影象的邊界(OpenCV 也提供了 canny 運算元、sobel 運算元等)。
這裡我們使用 模版匹配演算法(matchTemplate),他幫助演算法在一副影象中找到特定的目標。該函式需要四個引數,
- 原圖 Image
- 監測目標 detect
- 匹配結果圖 result
- 匹配衡量方式 method
- CV_TM_SQDIFF,平方差
- CV_TM_SQDIFF_NORMED,平方差歸一化
- CV_TM_CCORR,相關度
- CV_TM_CCORR_NORMED,相關度歸一化
- CV_TM_CCOEFF,相關係數
- CV_TM_CCOEFF_NORMED,相關係數歸一化
因此,該搜尋主要是以畫素級別的匹配,不會進行縮放;
我們目前的任務中王思聰的色調並沒有改變,因此任何一種方法的差異並不是很大。
import numpy as np from matplotlib import pyplot as plt img = cv2.imread('image.jpg') template = cv2.imread('detect.png') # Apply template Matching res = cv2.matchTemplate(img,template,eval('cv2.TM_CCOEFF')) # Get the size of template w, h = template[:,:,0].shape[::-1]複製程式碼
3.在王思聰周圍畫個紅框 —— minMaxLoc(OpenCV);
matchTemplate 函式得到的結果是一個灰度數值圖,給出的是影象中每一個 detect 範圍的匹配程度,灰度數值越大,則相似度越高。
為了畫出這個最有可能出現思聰王的位置,我們使用 OpenCVv 的 minMaxLoc 函式來得到思聰王邊框的具體位置,並進一步使用 OpenCV 的 rectangle 函式來畫出這個框。
# Get anchor for templateMatch result min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # draw rectangle top_left = max_loc bottom_right = (top_left[0] + w, top_left[1] + h) imgplt = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) cv2.rectangle(imgplt,top_left, bottom_right, 255, 2) # show image plt.imshow(imgplt) plt.title('Detected results'), plt.xticks([]), plt.yticks([]) plt.show() 複製程式碼
結果如上!成功!
4.計算機的速度 —— timeit。
Python 的 timeit 模組能夠提供 程式碼運算時間 的統計,在使用這一模組的使用,總共記錄兩次時間。一次在所有程式碼執行之前,一次在所有程式碼執行之後,兩次相減就得到的 程式碼運算的 總時間。
這裡列出了 timeit 時間統計的方式,但是在具體執行的時候,則需要把上述程式碼全部放在兩次時間獲取的中間,也就是下述第四行的位置。
import timeit start = timeit.default_timer() # All your code above stop = timeit.default_timer() print('Time: ', stop - start) 複製程式碼
我平均跑了十次,2018 年款的 MacBook Air,基本配置的平均時間是 0.2 秒!
目標達成!
PS,:point_up_2:是為了展示一下 OpenCV 的風采。因此使用了傳統的模式匹配流程。如果我們在實際應用中,面對雷同的問題。
- 首先分析認為,王思聰的臉部顏色和鴨子不一樣,且他的臉部顏色只有他獨有的;
- 可以使用 滴管 功能來得到 王思聰臉部顏色的 RGB;
- 在圖中搜索有 臉部顏色 RGB 的部分 並 高亮;
- 找到 王思聰!
OpenCV 是 計算機視覺 中非常重要的類庫,他既可以支援傳統計算機視覺處理,也可以支援 深度學習計算機視覺。他的底層是 C++,運算速度很快,也提供了 Python 的呼叫介面,真的省了很多事呢!
感謝觀看!