opencv學習之基礎

Jeff.Zhong發表於2022-05-11

前段時間一直在鑽研深度學習中的卷積神經網路,其中的預處理環節可以說非常關鍵,主要就是對圖片和視訊進行處理。而影像處理就涉及到圖形學和底層技術細節,這是一個比較精深和專業的領域,假設我們要從頭開始做起,那簡直太麻煩和低效了。為解決這個問題,openCV就此應運而生,它遮蔽了很多底層技術細節,抽象出方便的API,而我們只需要靈活組合相關的 api 就能實現強大的功能。

內容大綱

  1. 構建openCV.js
  2. opencv基礎操作

構建openCV.js

openCV有各種語言的版本,比較常用的是C++Python,也有JavaScript版本,因為基於js可以更快的驗證和檢視效果,同時也是因為本人不太擅長C++Python,真的是有了 js 這把錘子把什麼問題都看成釘子了?。當然前提是因為目前V8引擎和wasm效能足夠強悍,很多輕量級的需求完全可以放在前端來完成。

  1. 安裝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
    
  2. 下載openCV原始碼

    安裝完編譯器,接著就是獲取openCV的原始碼

    git clone https://github.com/opencv/opencv.git
    
  3. 打包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基礎操作

  1. 執行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> 
    
  2. 矩陣操作,矩陣就是一個多維陣列,而圖片就是二維陣列,這些基礎操作我認為也是挺有用的。

    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);//矩陣非運算
    
  3. 資料結構型別,這個型別也可以瞭解一下

    //點
    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做很多有趣的操作了,敬請期待。

相關文章