windows 安裝 opencv4nodejs

基本環(huán)境(不推薦用其他版本)
軟件包 版本
node >= 16.0.0
python >= 3.8 & <=3.10
cmake 3.26.0
opencv >= 4.6
1. 安裝cmake并配置環(huán)境變量

下載地址:https://github.com/Kitware/CMake/releases
我選擇的版本:cmake-3.26.0-windows-x86_64.msi
安裝的時(shí)候選擇添加環(huán)境變量就不用手動(dòng)加了

2. 安裝windows-build-tools

需要在管理員模式下安裝惜犀, 右鍵Window圖標(biāo) - 終端(管理員)
npm install --global windows-build-tools
安裝之后重啟終端

3.安裝opencv4.6

下載地址:https://nchc.dl.sourceforge.net/project/opencvlibrary/4.6.0/opencv-4.6.0-vc14_vc15.exe
安裝后設(shè)置環(huán)境變量璧眠, 我的opencv安裝在C:\tools\

環(huán)境變量名
OPENCV_INCLUDE_DIR C:\tools\opencv\build\include
OPENCV_LIB_DIR C:\tools\opencv\build\x64\vc15\lib
OPENCV_BIN_DIR C:\tools\opencv\build\x64\vc15\bin
OPENCV4NODEJS_AUTOBUILD_OPENCV_VERSION 4.6.0
OPENCV4NODEJS_DISABLE_AUTOBUILD 1

package.json中添加代碼(我的opencv安裝在C:\tools, 路徑根據(jù)實(shí)際情況改)

"opencv4nodejs": {
    "disableAutoBuild": 1,
    "opencvIncludeDir": "C:\\tools\\opencv\\build\\include",
    "opencvLibDir": "C:\\tools\\opencv\\build\\x64\\vc15\\lib",
    "opencvBinDir": "C:\\tools\\opencv\\build\\x64\\vc15\\bin",
    "autoBuildOpencvVersion": "4.6.0"
  }
4. 在命令行中執(zhí)行語(yǔ)句(管理員模式)

cnpm i @u4/opencv4nodejs -g
cnpm i node-gyp -g
npm link
build-opencv --version 4.6.0 rebuild
安裝之后重啟終端!

5. 在項(xiàng)目中安裝@u4/opencv4nodejs

不能用cnpm, 這一步只是從全局node_modules復(fù)制過(guò)來(lái), 如果不需要安裝到全局, 可以第4步不加-g
npm install -S @u4/opencv4nodejs

6. 項(xiàng)目中使用
 const cv = require('@u4/opencv4nodejs')
7. 環(huán)境檢查腳本, 復(fù)制保存成package.json同級(jí)的install.js文件, node install.js運(yùn)行這個(gè)js文件(終端需要管理員權(quán)限), 也可以根據(jù)commends這個(gè)數(shù)組中的命令, 自己一行一行跑一下
const fs = require('fs');
const { exec } = require('child_process');
const path = require('path');

let reminder = {
  node: { version: ">= 16.0.0"},
  python: { version: ">= 3.8 & <=3.10"},
  cmake: { version: "3.26.0"},
  opencv: { version: ">= 4.6"},
};
let opencvVariable = [
  {
    name: 'OPENCV_INCLUDE_DIR', 
    value: process.env.OPENCV_INCLUDE_DIR,
    example: 'C:\\tools\\opencv\\build\\include',
  },
  {
    name: 'OPENCV_BUILD_ROOT',  
    value: process.env.OPENCV_BUILD_ROOT,
    example: 'C:\\tools\\opencv',
  },
  {
    name: 'OPENCV_LIB_DIR', 
    value: process.env.OPENCV_LIB_DIR,
    example: 'C:\\tools\\opencv\\build\\x64\\vc15\\lib',
  },
  {
    name: 'OPENCV_BIN_DIR',
    value: process.env.OPENCV_BIN_DIR,  
    example: 'C:\\tools\\opencv\\build\\x64\\vc15\\bin',
  },
  {
    name: 'OPENCV4NODEJS_AUTOBUILD_OPENCV_VERSION', 
    value: process.env.OPENCV4NODEJS_AUTOBUILD_OPENCV_VERSION,  
    example: '4.7.0',
  },
  {
    name: 'OPENCV4NODEJS_DISABLE_AUTOBUILD',
    value: process.env.OPENCV4NODEJS_DISABLE_AUTOBUILD,     
    example: '1',
  },
]

console.log(`\n需要準(zhǔn)備的基本環(huán)境(都需要配置環(huán)境變量)\n`);
console.table(reminder);
console.log(`\nopencv環(huán)境變量\n`);
console.table(opencvVariable);
const isWin = (() => {
  return /^win/.test(process.platform);
})();
let _ = process.argv.splice(2);
let opencv = _[0] || process.env.OPENCV_BUILD_ROOT
const OPENCV4NODEJS_AUTOBUILD_OPENCV_VERSION = process.env.OPENCV4NODEJS_AUTOBUILD_OPENCV_VERSION || '4.6.0'



const execCmd = (cmd, path) => {
  return new Promise((resolve, reject) => {
    try {
      exec(cmd, { cwd: path }, (err, stdout, stderr) => {
        if (stdout) {
          resolve(stdout);
          return;
        }
        reject(err || stderr);
      });
    } catch (e) {
      reject(e);
    }
  });
};

const commends = [
  {
    cmd: 'node -v',
    error: 'node未安裝',
    after: (stdout) => {
      const strs = stdout.match(/(0|[1-9]\d*)\./, 'g');
      if (strs[1] !== '16') {
        console.error('node版本不等于16')
      } else {
        console.log(`node版本: ${stdout}`)
      }
    }
  },
  {
    cmd: 'python -V',
    error: 'python未安裝',
    after: (stdout) => {
      const strs = stdout.match(/(0|[1-9]\d*)\./, 'g');
      const strs2 = stdout.match(/\.(0|[1-9]\d*)\./, 'g');
      if (strs[1] !== '3') {
        console.error('python版本不等于3')
      } else if ( strs2[1] > 10 || strs2[1] < 8 ) {
        console.error(`python版本范圍是3.8至3.10, 當(dāng)前環(huán)境為${stdout}`)
      } else {
        console.log(`python版本: ${stdout}`)
      }
    }
  },
  {
    cmd: 'cmake -version',
    error: 'cmake未安裝',
    after: (stdout) => {
      const strs = stdout.match(/(0|[1-9]\d*)\.(0|[1-9]\d*)/, 'g');
      if (strs[1] !== '3.26') {
        console.error('cmake版本不等于3.26')
      } else {
        console.log(`cmake版本: ${stdout}`)
      }
    }
  },
  {
    before: () => console.log(`根據(jù)OPENCV_BUILD_ROOT環(huán)境變量, 修改package.json文件`),
    cmd: '',
    error: 'opencv訪問(wèn)路徑錯(cuò)誤, 請(qǐng)確定OPENCV_BUILD_ROOT環(huán)境變量是否正確',
    after: () => {
      try {
        let opencvIncludeDir = ''
        let opencvLibDir = ''
        let opencvBinDir = ''
        if (isWin) {
          opencvIncludeDir = path.join(opencv, '\\build\\include').replaceAll('\\', '\\\\')
          opencvLibDir = path.join(opencv, '\\build\\x64\\vc15\\lib').replaceAll('\\', '\\\\')
          opencvBinDir = path.join(opencv, '\\build\\x64\\vc15\\bin').replaceAll('\\', '\\\\')
        } else {
          opencvIncludeDir = path.join(opencv, '/build/include')
          opencvLibDir = path.join(opencv, '/build/x64/vc15/lib')
          opencvBinDir = path.join(opencv, '/build/x64/vc15/bin')
        }
        fs.statSync(opencvIncludeDir);
        fs.statSync(opencvLibDir);
        fs.statSync(opencvBinDir);
        const data = fs.readFileSync('./package.json', 'utf8');
        let newData
        newData = data.replace(/"opencvIncludeDir": ".*"/gi, `"opencvIncludeDir": "${opencvIncludeDir}"`)
        newData = newData.replace(/"opencvLibDir": ".*"/gi, `"opencvLibDir": "${opencvLibDir}"`)
        newData = newData.replace(/"opencvBinDir": ".*"/gi, `"opencvBinDir": "${opencvBinDir}"`)
        newData = newData.replace(/"autoBuildOpencvVersion": ".*"/gi, `"autoBuildOpencvVersion": "${OPENCV4NODEJS_AUTOBUILD_OPENCV_VERSION}"`)
        fs.writeFileSync('./package.json', newData)
      } catch (error) {
        throw error
      }
    }
  },
  {
    cmd: 'cnpm -v',
    error: 'cnpm未安裝, 運(yùn)行 npm install -g cnpm --registry=https://registry.npm.taobao.org 安裝cnpm后重試',
    after: () => console.log('將使用cnpm安裝依賴')
  },
  {
    before: () => console.log(`@u4/opencv4nodejs 安裝`),
    cmd: 'cnpm i @u4/opencv4nodejs -g',
    error: '@u4/opencv4nodejs 安裝失敗',
    after: () => console.log('@u4/opencv4nodejs 已安裝到全局')
  },
  {
    before: () => console.log(`node-gyp 安裝`),
    cmd: 'cnpm i node-gyp -g',
    error: 'node-gyp 安裝失敗',
    after: () => console.log('node-gyp 已安裝到全局')
  },
  {
    before: () => console.log(`npm link 安裝`),
    cmd: 'npm link',
    error: 'npm link 安裝失敗',
    after: () => console.log('npm link 運(yùn)行成功')
  },
  {
    before: () => console.log(`build-opencv opencv 構(gòu)建`),
    cmd: `build-opencv --version ${OPENCV4NODEJS_AUTOBUILD_OPENCV_VERSION} rebuild`,
    error: 'build-opencv 打包失敗',
    after: () => console.log('opencv 構(gòu)建成功')
  },
  {
    before: (cmd) => console.log(`執(zhí)行命令${cmd}, 這一步有點(diǎn)久, 10分鐘左右`),
    cmd: 'npm run install',
    error: '安裝依賴失敗, 刪除項(xiàng)目下的node_modules文件后重試',
    after: () => console.log('依賴安裝完畢')
  },
];



(async () => {
  for (let index = 0; index < commends.length; index++) {
    const commend = commends[index];
    let {
      cmd,
      before,
      after,
      error
    } = commend
    try {
      let stdout
      before && before(cmd)
      if (cmd) {
        stdout = await execCmd(cmd);
      }
      after && after(stdout)
    } catch (e) {
      throw `${error || ''} >> ${e}`
    }
  }
})()

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末虱朵,一起剝皮案震驚了整個(gè)濱河市痒玩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌族壳,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異补履,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)剿另,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門箫锤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人雨女,你說(shuō)我怎么就攤上這事谚攒。” “怎么了氛堕?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵馏臭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我岔擂,道長(zhǎng)位喂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任乱灵,我火速辦了婚禮塑崖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘痛倚。我一直安慰自己规婆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著抒蚜,像睡著了一般掘鄙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嗡髓,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天操漠,我揣著相機(jī)與錄音,去河邊找鬼饿这。 笑死浊伙,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的长捧。 我是一名探鬼主播嚣鄙,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼串结!你這毒婦竟也來(lái)了哑子?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤肌割,失蹤者是張志新(化名)和其女友劉穎卧蜓,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體把敞,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烦却,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了先巴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡冒冬,死狀恐怖伸蚯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情简烤,我是刑警寧澤剂邮,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站横侦,受9級(jí)特大地震影響挥萌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜枉侧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一引瀑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧榨馁,春花似錦憨栽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)屡萤。三九已至,卻和暖如春掸宛,著一層夾襖步出監(jiān)牢的瞬間死陆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工唧瘾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留措译,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓劈愚,卻偏偏與公主長(zhǎng)得像瞳遍,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子菌羽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容