前段時間一直在鑽研深度學習中的卷積神經網路,其中的預處理環節可以說非常關鍵,主要就是對圖片和視訊進行處理。而影像處理就涉及到圖形學和底層技術細節,這是一個比較精深和專業的領域,假設我們要從頭開始做起,那簡直太麻煩和低效了。為解決這個問題,openCV就此應運而生,它遮蔽了很多底層技術細節,抽象出方便的API,而我們只需要靈活組合相關的 api 就能實現強大的功能。
內容大綱
- 構建openCV.js
- opencv基礎操作
構建openCV.js
openCV有各種語言的版本,比較常用的是C++ 和Python,也有JavaScript版本,因為基於js可以更快的驗證和檢視效果,同時也是因為本人不太擅長C++和Python,真的是有了 js 這把錘子把什麼問題都看成釘子了?。當然前提是因為目前V8引擎和wasm效能足夠強悍,很多輕量級的需求完全可以放在前端來完成。
-
安裝Emscripten
openCV是基於C/C++的,我們要用js版本的openCV,需要做轉換,這就需要Emscripten 這個編譯器了。
Emscripten 是一個基於LLVM的編譯器,可以將C/C++語言編譯為JavaScript。我們按著官網步驟一步一步下載安裝就好:
# Get the emsdk repo git clone https://github.com/emscripten-core/emsdk.git # Enter that directory cd emsdk # Fetch the latest version of the emsdk (not needed the first time you clone) git pull # Download and install the latest SDK tools. ./emsdk install latest # Make the "latest" SDK "active" for the current user. (writes .emscripten file) ./emsdk activate latest # Activate PATH and other environment variables in the current terminal source ./emsdk_env.sh
-
下載openCV原始碼
安裝完編譯器,接著就是獲取openCV的原始碼
git clone https://github.com/opencv/opencv.git
-
打包openCV.js
工具鏈和原始碼都準備完畢,最後一步還需要安裝Python,步驟確實有點多,Python的安裝就不提了,下載包安裝或者homebrew安裝都可以,我們直接看打包的命令吧,預設打包為asm,我們選webAssembly版本的,最後從build_wasm拷貝出opencv.js。
cd opencv #進入opencv目錄 python ./platforms/js/build_js.py build_js # default asm python ./platforms/js/build_js.py build_wasm --build_wasm # build wasm
opencv基礎操作
-
執行openCV.js,cv 預設是一個Promise,因此需要非同步才能獲取出openCV全域性物件。
這裡只做最簡單的操作,讀取圖片,轉換灰度圖,顯示圖片
<canvas id="canvas" width="300" height="300"></canvas> <script src="./opencv.js"></script> <script> const canvas = document.createElement('canvas'); let CV; async function init() { CV = await cv; console.log('cv: ', CV); const img = new Image(); img.src = './img.png'; img.onload = function () { const src = CV.imread(img);//讀取圖片 const dst = new CV.Mat(); CV.cvtColor(src, dst, CV.COLOR_RGBA2GRAY);//轉換為灰度圖 CV.imshow(canvas, dst);//顯示圖片 src.delete(); dst.delete(); }; } init(); </script>
-
矩陣操作,矩陣就是一個多維陣列,而圖片就是二維陣列,這些基礎操作我認為也是挺有用的。
const mat = new cv.Mat();// 預設矩陣 const mat = new cv.Mat(rows, cols, type);// 型別二維矩陣 const mat = new cv.Mat(rows, cols, type, new cv.Scalar());// 有初始值的型別二維矩陣 const mat = cv.Mat.zeros(rows, cols, type);//全部填充為0 const mat = cv.Mat.ones(rows, cols, type);//全部填充為1 const mat = cv.Mat.eye(rows, cols, type); //單位矩陣 const mat = cv.matFromArray(rows, cols, type, array);//由陣列構建矩陣 const mat = cv.matFromImageData(imgData);//由圖片構建矩陣 const dst = src.clone();//克隆 src.copyTo(dst, mask);//根據mask拷貝 cv.add(src1, src2, dst, mask, dtype);//矩陣相加 cv.subtract(src1, src2, dst, mask, dtype);//矩陣相減 cv.bitwise_and(roi, roi, imgBg, maskInv);//矩陣與運算 cv.bitwise_or(roi, roi, imgBg, maskInv);//矩陣或運算 cv.bitwise_xor(roi, roi, imgBg, maskInv);//矩陣異或運算 cv.bitwise_not(mask, maskInv);//矩陣非運算
-
資料結構型別,這個型別也可以瞭解一下
//點 const point = new cv.Point(x, y); const point = {x: x, y: y}; //向量 let scalar = new cv.Scalar(R, G, B, Alpha); let scalar = [R, G, B, Alpha]; //大小 const size = new cv.Size(width, height); const size = {width : width, height : height}; //圓形 let circle = new cv.Circle(center, radius); let circle = {center : center, radius : radius}; //矩形 let rect = new cv.Rect(x, y, width, height); let rect = {x : x, y : y, width : width, height : height}; //旋轉矩形 let rotatedRect = new cv.RotatedRect(center, size, angle); let rotatedRect = {center : center, size : size, angle : angle};
總結
打包構建出openCV.js,同時也學習了openCV相關的基礎。後面我們就可以基於openCV做很多有趣的操作了,敬請期待。