OpenCV-Python實戰(20)——OpenCV計算機視覺專案在Web端的部署
- 0. 前言
- 1. Python Web 框架簡介
- 2. Flask 安裝與使用
- 2.1 Flask 安裝
- 2.2 Flask 框架 Hello World 使用示例
- 2.2 擴展 Hello World 應用程式以在網路中其他計算機訪問
- 2.2 擴展 Hello World 應用程式以系結其它 URL
- 3. 使用 OpenCV 和 Flask 構建 Web 計算機視覺應用程式
- 3.1 Web 計算機視覺應用示例——影像卡通化
- 3.2 Web 計算機視覺應用示例——增強現實
- 小結
- 系列鏈接
0. 前言
將 OpenCV 計算機視覺專案部署在 Web 端一個有趣的話題,部署在 Web 端的優勢之一是不需要安裝任何應用,只需要訪問地址就可以訪問應用,有很多 Python Web 框架可用于部署應用程式,這些框架可以使我們專注于應用程式的核心邏輯,而不必處理低級細節(例如,協議、套接字或行程和執行緒管理等),在本文中,將使用 Flask 框架,以構建計算機視覺 Web 應用程式,
1. Python Web 框架簡介
使用 Python Web 框架可以使我們專注于應用程式的核心邏輯,而不必處理低級細節)例如,協議、套接字或行程以及執行緒管理等),這些框架可以分為全堆疊和非全堆疊框架:
- Django 是一個免費的、開源的全堆疊框架,
Django使創建Web應用程式變得非常容易,并且比其他框架需要更少的時間,并專注于盡可能實作自動化, - Flask 是非全堆疊框架,Flask 具有以下依賴項:
- Werkzeug WSGI 工具包:
WSGI實用程式庫 - Jinja2:模板引擎
- Werkzeug WSGI 工具包:
Django 和 Flask 均可用于部署開發計算機視覺和深度學習應用程式,但 Flask 的學習曲線更平滑,且 Flask 專注于極簡主義,例如,Flask 的 Hello World 應用程式只有幾行代碼,因此建議將 Flask 用于較小且不太復雜的應用程式,而 Django 通常用于較大且較復雜的應用程式,在本文中,將使用 Flask 來構建計算機視覺 Web 應用程式,
2. Flask 安裝與使用
2.1 Flask 安裝
為了使用 Flask 構建計算機視覺 Web 應用程式,首先進行安裝:
$ pip install flask
2.2 Flask 框架 Hello World 使用示例
不可避免的,作為約定俗成的規矩,首先撰寫 Hello World 應用程式來了解 Flask 框架:
# hello.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello world!'
if __name__ == '__main__':
app.run()
匯入所需的包后,首先創建 Flask 類的實體,作為 Web 服務器網關介面 (Web Server Gateway Interface, WSGI) 應用程式,route() 裝飾器用于指示對應 URL 應該觸發的函式,換句話說在 Flask 中,使用 route() 裝飾器將函式系結到指定 URL,
使用以下命令啟動執行 Hello World 應用程式:
$ python hello.py
啟動執行后,可以在控制臺中看到以下訊息,表明 Web 服務器已啟動:
* Serving Flask app "hello" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
此時,在瀏覽器中訪問 http://127.0.0.1:5000/,將對服務器發送 GET 請求,該請求將回傳相應的訊息:

2.2 擴展 Hello World 應用程式以在網路中其他計算機訪問
上一示例中,只能從本機訪問我們構建的服務器,而不能從網路中的其他計算機訪問,為了使服務器公開可用,運行服務器應用程式時應添加引數 host=0.0.0.0:
# hello_ex.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello world!'
if __name__ == '__main__':
app.run(host='0.0.0.0')
這樣,就可以從連接到該網路的其他設備執行請求,如下圖所示,處于同一網路下的移動設備也可以訪問我們的服務器了:

2.2 擴展 Hello World 應用程式以系結其它 URL
可以使用 route() 裝飾器將函式系結到 URL,接下來,我們就擴展 Hello World 應用程式以系結其它 URL:
# hello_ex_route.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello world!'
@app.route('/user')
def hello_user():
return 'Hello user!'
if __name__ == '__main__':
app.run(host='0.0.0.0')
在下圖中,我們可以看到移動端請求同一網路下服務器 URL http://10.140.12.255:5000/user 并回傳結果 Hello user! 資訊:

我們已經介紹了使用 Flask 創建應用程式時的基本概念,接下來,我們就來探究如何使用 OpenCV 和 Flask 創建 Web 計算機視覺應用程式,
3. 使用 OpenCV 和 Flask 構建 Web 計算機視覺應用程式
接下來,我們將使用 OpenCV 和 Flask 創建 Web 計算機視覺應用程式,我們使用 OpenCV 和 Flask 的構建簡單的計算機視覺中的 Hello world 應用程式,
3.1 Web 計算機視覺應用示例——影像卡通化
撰寫程式 opencv_flask_hello_world.py 介紹結合 OpenCV 執行基本的 Web 計算機視覺應用程式:
# opencv_flask_hello_world.py
import cv2
import numpy as np
from flask import Flask, request, make_response
import urllib.request
app = Flask(__name__)
@app.route('/cartoon', methods=['GET'])
def cartoon_processing():
# 讀取影像
with urllib.request.urlopen(request.args.get('url')) as url:
image_array = np.asarray(bytearray(url.read()), dtype=np.uint8)
# 將影像轉換為 OpenCV 格式
img_opencv = cv2.imdecode(image_array, -1)
# 影像卡通化
sketch_gray, sketch_color = cv2.pencilSketch(img_opencv, sigma_s=20, sigma_r=0.1, shade_factor=0.1)
stylizated_image = cv2.stylization(img_opencv, sigma_s=60, sigma_r=0.07)
# 壓縮影像并將其存盤在記憶體緩沖區中
retval, buffer = cv2.imencode('.jpg', stylizated_image)
# 構建頁面回應
response = make_response(buffer.tobytes())
response.headers['Content-Type'] = 'image/jpeg'
return response
if __name__ == '__main__':
app.run(host='0.0.0.0')
接下來,我們通過分解以上步驟進行詳細解釋:
- 第一步是匯入需要的包,上例中使用了
route()裝飾器將cartoon_processing()函式系結到/cartoon URL;此外,還需要url引數才能正確執行GET請求,為了獲取這個引數,需要使用request.args.get()函式,最后還需要使用make_response()函式構造回應資訊; - 然后需要讀取傳遞到此
URL的影像,將其轉換為陣列:
with urllib.request.urlopen(request.args.get('url')) as url:
image_array = np.asarray(bytearray(url.read()), dtype=np.uint8)
- 接下來將影像轉換為
OpenCV格式,并進行卡通化處理(關于影像卡通化更詳細的介紹可以參考《OpenCV實作影像卡通化》):
# 將影像轉換為 OpenCV 格式
img_opencv = cv2.imdecode(image_array, -1)
# 影像卡通化
sketch_gray, sketch_color = cv2.pencilSketch(img_opencv, sigma_s=20, sigma_r=0.1, shade_factor=0.1)
stylizated_image = cv2.stylization(img_opencv, sigma_s=60, sigma_r=0.07)
- 然后對影像進行壓縮并存入記憶體緩沖區:
# 壓縮影像并將其存盤在記憶體緩沖區中
retval, buffer = cv2.imencode('.jpg', stylizated_image)
- 最后一步是構建并回傳回應給客戶端:
# 構建頁面回應
response = make_response(buffer.tobytes())
response.headers['Content-Type'] = 'image/jpeg'
return response
接下來運行此腳本:
$ python opencv_flask_hello_world.py
服務器運行后,我們就可以從客戶端執行 GET 請求,我們將獲得處理后的影像,如下圖所示:

如上圖所示,我們呼叫了以下 GET 請求:
# 這里的 10.140.12.255 是我的局域網 ip,需要根據自己的 ip 修改
http://10.140.12.255:5000/cartoon?url=https://imgs.mmkk.me/wmnv/img/20190625070725-5d11c82dd1cfd.jpg
其中,引數 url 的值 https://imgs.mmkk.me/wmnv/img/20190625070725-5d11c82dd1cfd.jpg 是我們想要 Web 計算視覺應用程式處理的影像,因此可以通過修改 url 引數值來處理不同影像:

3.2 Web 計算機視覺應用示例——增強現實
接下來,我們結合增強現實相關知識,構建另一個計算機視覺應用示例:
import cv2
import numpy as np
from flask import Flask, request, make_response
import urllib.request
app = Flask(__name__)
@app.route('/ar', methods=['GET'])
def ar_processing():
# 加載級聯檢測器
face_cascade = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
eyepair_cascade = cv2.CascadeClassifier("haarcascade_mcs_eyepair_big.xml")
img_glasses = cv2.imread('glasses.png', -1)
img_glasses_mask = img_glasses[:, :, 3]
img_glasses = img_glasses[:, :, 0:3]
with urllib.request.urlopen(request.args.get('url')) as url:
image_array = np.asarray(bytearray(url.read()), dtype=np.uint8)
# 將影像轉換為 OpenCV 格式
img_opencv = cv2.imdecode(image_array, -1)
# 將其轉換為灰度影像
gray = cv2.cvtColor(img_opencv, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
roi_gray = gray[y:y + h, x:x + w]
roi_color = img_opencv[y:y + h, x:x + w]
# 在檢測到的人臉中檢測眼睛
eyepairs = eyepair_cascade.detectMultiScale(roi_gray)
for (ex, ey, ew, eh) in eyepairs:
# 計算“眼睛”掛件放置的坐標
x1 = int(ex - ew / 10)
x2 = int((ex + ew) + ew / 10)
y1 = int(ey)
y2 = int(ey + eh + eh / 2)
if x1 < 0 or x2 < 0 or x2 > w or y2 > h:
continue
# 計算“眼睛”掛件放置區域大小
img_glasses_res_width = int(x2 - x1)
img_glasses_res_height = int(y2 - y1)
mask = cv2.resize(img_glasses_mask, (img_glasses_res_width, img_glasses_res_height))
mask_inv = cv2.bitwise_not(mask)
img = cv2.resize(img_glasses, (img_glasses_res_width, img_glasses_res_height))
roi = roi_color[y1:y2, x1:x2]
roi_bakground = cv2.bitwise_and(roi, roi, mask=mask_inv)
roi_foreground = cv2.bitwise_and(img, img, mask=mask)
res = cv2.add(roi_bakground, roi_foreground)
roi_color[y1:y2, x1:x2] = res
break
# 壓縮影像并將其存盤在記憶體緩沖區中
retval, buffer = cv2.imencode('.jpg', img_opencv)
# 構建回應資訊
response = make_response(buffer.tobytes())
response.headers['Content-Type'] = 'image/jpeg'
return response
if __name__ == '__main__':
app.run(host='0.0.0.0')
接下來運行此腳本:
$ python opencv_flask_hello_world_2.py
服務器運行后,我們就可以從客戶端執行 GET 請求,我們將獲得處理后的影像,如下圖所示:

如上圖所示,我們呼叫了以下 GET 請求:
# 這里的 10.140.12.255 是我的局域網 ip,需要根據自己的 ip 修改
http://10.140.12.255:5000/ar?url=https://imgs.mmkk.me/wmnv/img/20190625073459-5d11cea35c407.png
我們也可以通過簡單修改上述腳本,應用此前學習的其他影像處理技術,構建更多有趣實用的 OpenCV 網路計算視覺應用程式,
小結
本文中,我們了解了如何使用 Python Web 框架創建 Web 應用程式,更具體地說,我們使用 OpenCV 和 Flask 開發了多個 Web 計算機視覺應用程式,我們還看到了如何執行來自瀏覽器的請求,以及使用 OpenCV 和 Flask 創建 Web API,
系列鏈接
OpenCV-Python實戰(1)——OpenCV簡介與影像處理基礎
OpenCV-Python實戰(2)——影像與視頻檔案的處理
OpenCV-Python實戰(3)——OpenCV中繪制圖形與文本
OpenCV-Python實戰(4)——OpenCV常見影像處理技術
OpenCV-Python實戰(5)——OpenCV影像運算
OpenCV-Python實戰(6)——OpenCV中的色彩空間和色彩映射
OpenCV-Python實戰(7)——直方圖詳解
OpenCV-Python實戰(8)——直方圖均衡化
OpenCV-Python實戰(9)——OpenCV用于影像分割的閾值技術
OpenCV-Python實戰(10)——OpenCV輪廓檢測
OpenCV-Python實戰(11)——OpenCV輪廓檢測相關應用
OpenCV-Python實戰(12)——一文詳解AR增強現實
OpenCV-Python實戰(13)——OpenCV與機器學習的碰撞
OpenCV-Python實戰(14)——人臉檢測詳解
OpenCV-Python實戰(15)——面部特征點檢測詳解
OpenCV-Python實戰(16)——人臉追蹤詳解
OpenCV-Python實戰(17)——人臉識別詳解
OpenCV-Python實戰(18)——深度學習簡介與入門示例
OpenCV-Python實戰(19)——OpenCV與深度學習的碰撞
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/431061.html
標籤:AI
上一篇:R語言KMeans聚類分析確定最優聚類簇數實戰:間隙統計Gap Statistic(確定最優聚類簇數)
下一篇:新IDE出現,程式員迎來危機?
