Node Opencv Addon
Opencv Node Addon
Opencv 安装使用
下载Opencv安装包: http://opencv.org/releases.html
解压进入Opencv目录
编译Opencv(需要cmake)
mkdir release
cd release
cmake -G "Unix Makefiles" .. (为Unix 系统生成Makefile,Mac OSX是基于Unix的。未安装cmake 可以通过Homebrew安装,未安装Homebrew需安装Homebrew)
make
安装Opencv
make install
安装完成的目录
/usr/local/lib (Opencv库文件)
/usr/local/include (Opencv头文件)
/usr/local/share/ (Opencv xml配置文件)
使用Opencv(C++ Version)
编写CMakeLists.txt文件
project( ORBFeatureAndCompare ) // 项目的名称 cmake_minimum_required(VERSION 2.8) // cmake的版本要求 find_package( OpenCV REQUIRED ) // 查找对应的Opencv依赖库 find_package(Boost COMPONENTS log log_setup thread filesystem system) // 查找对应的Boost依赖库(下文出现Boost的安装方法) add_executable( ORBFeatureAndCompare ORBFeatureAndCompare ) // 指定可运行的文件 // 引入对应的依赖库文件的位置 target_link_libraries(ORBFeatureAndCompare${OpenCV_LIBS}${Boost_LOG_SETUP_LIBRARY}${Boost_LOG_LIBRARY}${Boost_FILESYSTEM_LIBRARY}${Boost_THREAD_LIBRARY}${Boost_SYSTEM_LIBRARY} )
编写Opencv的cpp文件
//必要的头文件 #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/features2d/features2d.hpp> #include <boost/filesystem.hpp> #include <boost/filesystem/fstream.hpp> #include <iostream> #include <fstream> #include <cstring> #include <iterator> #include <vector>using namespace boost::filesystem; namespace newfs = boost::filesystem; using namespace cv; using namespace std;int main () {....return 0; }
创建一个images(其他命名都可以)的资源文件夹
cd images cmake .. make ./ORBFeatureAndCompare //编译出的可执行程序
安装使用Boost进行数据序列化
下载Boost安装包: https://dl.bintray.com/boosto...
解压进入Boost目录
编译安装Boost
./bootstrap.sh
./b2
引入Boost库进行数据序列化,同样是在CmakeList中引入文件路径, 在cpp文件中使用
封装cpp程序为Node Addon
依赖安装
全局安装node-gyp
本地安装nan
编写binding.gyp
{"targets": [{"target_name": "feature","sources": [ "./src/feature.cc" ],"include_dirs": ["<!(node -e \"require('nan')\")","/usr/local/include/boost","/usr/local/include/opencv2"],"conditions": [[ "OS==\"linux\" or OS==\"freebsd\" or OS==\"openbsd\" or OS==\"solaris\" or OS==\"aix\"", {}],["OS==\"mac\"", {"libraries": ["/usr/local/lib/libboost_log_setup-mt.dylib","/usr/local/lib/libboost_log-mt.dylib","/usr/local/lib/libboost_filesystem-mt.dylib","/usr/local/lib/libboost_thread-mt.dylib","/usr/local/lib/libboost_system-mt.dylib","/usr/local/lib/libopencv_core.3.2.0.dylib","/usr/local/lib/libopencv_highgui.3.2.0.dylib","/usr/local/lib/libopencv_imgproc.3.2.0.dylib","/usr/local/lib/libopencv_features2d.3.2.0.dylib"]}]]}] }
编写node c++ 插件
#include <node.h>
#include <nan.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <iterator>
#include <vector>using namespace boost::filesystem;
namespace newfs = boost::filesystem;
using namespace v8;
using namespace std;vector<uchar> matToString(cv::Mat descriptorMat) {vector<uchar> buf;imencode(".png", descriptorMat, buf);return buf;
}vector<uchar> descriptorMat(cv::Mat image) {vector<cv::KeyPoint> keyPoint;cv::Ptr<cv::ORB> orb = cv::ORB::create(4000, 1.2f, 8, 31, 0, 2, cv::ORB::HARRIS_SCORE, 31, 20);orb->detect(image, keyPoint);cv::Mat descriptorMat;orb->compute(image, keyPoint, descriptorMat);return matToString(descriptorMat);
}void imageFeature(const FunctionCallbackInfo<Value>& args) {Isolate* isolate = args.GetIsolate();if (args.Length() < 1) {isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Wrong number of arguments")));return;}if (!args[0]->IsString()) {isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Wrong arguments")));return;}String::Utf8Value pathValue(Local<String>::Cast(args[0]));string path = string(*pathValue);cv::Mat image = cv::imread(path, 1);if (image.empty()) {isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Input image error")));return;}vector<uchar> descriptorString = descriptorMat(image);Local<Object> buf = Nan::NewBuffer(descriptorString.size()).ToLocalChecked();uchar* data = (uchar*) node::Buffer::Data(buf);memcpy(data, &descriptorString[0], descriptorString.size());v8::Local<v8::Object> globalObj = Nan::GetCurrentContext()->Global();v8::Local<v8::Function> bufferConstructor = v8::Local<v8::Function>::Cast(globalObj->Get(Nan::New<String>("Buffer").ToLocalChecked()));v8::Local<v8::Value> constructorArgs[3] = {buf, Nan::New<v8::Integer>((unsigned)descriptorString.size()), Nan::New<v8::Integer>(0)};v8::Local<v8::Object> actualBuffer = bufferConstructor->NewInstance(3, constructorArgs);args.GetReturnValue().Set(actualBuffer);
}int bfMatcherCompare (cv::Mat &descriptors1, cv::Mat &descriptors2) {cv::BFMatcher matcher(cv::NORM_HAMMING);vector<cv::DMatch> matches;matcher.match(descriptors1, descriptors2, matches);double max_dist = 0;double min_dist = 100;/*for (int i = 0; i < descriptors1.rows; i++){double dist = matches[i].distance;if (dist < min_dist)min_dist = dist;if (dist > max_dist)max_dist = dist;}vector<cv::DMatch> good_matches;for (int i = 0; i < descriptors1.rows; i++){if (matches[i].distance < 3 * min_dist)good_matches.push_back(matches[i]);}return good_matches.size();*/for (int i = 0; i < descriptors1.rows; i++) {double dist = matches[i].distance;if (dist < min_dist) {min_dist = dist;}if (dist > max_dist) {max_dist = dist;}}std::vector<cv::DMatch> good_matches;double good_matches_sum = 0.0;for (int i = 0; i < descriptors1.rows; i++) {double distance = matches[i].distance;if (distance <= std::max(2 * min_dist, 0.02)) {good_matches.push_back(matches[i]);good_matches_sum += distance;}}return (double) good_matches_sum / (double) good_matches.size();
}void similarity(const FunctionCallbackInfo<Value>& args) {Isolate* isolate = args.GetIsolate();Local<Object> arg1 = args[0]->ToObject();int size1 = args[1]->NumberValue();Local<Object> arg2 = args[2]->ToObject();int size2 = args[3]->NumberValue();if (args.Length() < 4) {isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Wrong number of arguments")));return;}uchar*buffer1 = (uchar*) node::Buffer::Data(arg1);std::vector<uchar> vec1(buffer1, buffer1 + (unsigned int) size1);cv::Mat img_decode1;img_decode1 = cv::imdecode(vec1, CV_8U);uchar*buffer2 = (uchar*) node::Buffer::Data(arg2);std::vector<uchar> vec2(buffer2, buffer2 + (unsigned int) size2);cv::Mat img_decode2;img_decode2 = cv::imdecode(vec2, CV_8U);int similarity = bfMatcherCompare(img_decode1, img_decode2);args.GetReturnValue().Set(similarity);
}void init(Local<Object> exports, Local<Object> module) {NODE_SET_METHOD(exports, "imageFeature", imageFeature);NODE_SET_METHOD(exports, "similarity", similarity);
}NODE_MODULE(addon, init)
编写Js文件
const feature = require('./build/Release/feature');exports.getImageFeature = (filePath) => {return feature.imageFeature(filePath).toString('utf8');
};exports.getImageSimilarity = (descriptor1, descriptor2) => {let matBuffer1 = Buffer.from(descriptor1);let matBuffer2 = Buffer.from(descriptor2);return feature.similarity(matBuffer1, matBuffer1.length, matBuffer2, matBuffer2.length);
};
编译运行
node-gyp configure build
node test.js
Node Opencv Addon相关推荐
- 如何开发 Node.js Native Add-on?
简介: 来一起为 Node.js 的 add-on 生态做贡献吧~ 作者 | 吴成忠(昭朗) 这篇文章是由 Chengzhong Wu (@legendecas),Gabriel Schulhof ( ...
- 使用napi node_使用Napi / node-addon-api和Cmake的独立于Node.js版本的C ++ Native Addon
使用napi node This is a tutorial for c++ Node-addon-api / Napi addon using cmake.Napi makes it indepen ...
- 全网最全面的 Node.js 资源汇总推荐,4W Star!
作者@前哨君|地址@https://github.com/jobbole/awesome-nodejs-cn由于微信不支持外链,可文末 "阅读原文" 或打开 Github 地址查看 ...
- Github 4 万 Star!最全面的 Node.js 资源汇总推荐
点击"程序员成长指北",选择"星标????" 让一部分开发者看到未来 作者@前哨君|地址@https://github.com/jobbole/awesome- ...
- 最全面的 Node.js 资源汇总推荐
作者@前哨君|地址@https://github.com/jobbole/awesome-nodejs-cn [导读]:Node.js 是一个开源.跨平台的,用于编写服务器和命令行的 JavaScri ...
- 【Node】Node.js 资源汇总推荐
[导读]:Node.js 是一个开源.跨平台的,用于编写服务器和命令行的 JavaScript 运行时工具.awesome-nodejs 是sindresorhus发起维护的 Node.js 资源列表 ...
- nodejs addon binding osg
绑定过webpage 到osg 窗口,我需要一个回调机制对osg 显示进行后台显示. 具体的做法是osg作为一个状态机, 前台web界面向后台发送命令, 消息 . 后台接收消息,改变状态.我想架在so ...
- electron集成arm64架构的nodejs addon插件
随着macos M1芯片的发布,当前的electron PC应用要适配arm64架构(虽然低版本electron应用也可以在arm64架构上面运行(转译)但是这严重影响电脑性能). 环境搭建 mac上 ...
- 使用cdn和npm引入的区别_在npm上发布自己的vue组件库(使用npm install 或者 CDN的方式引用)...
一.npm publish 发布包到npm库的命令是npm publish npm publish发布包,需要先配置webpack.json文件,如果没有webpack.json文件,可以通过npm ...
最新文章
- 零基础学习UI设计有哪些简单有效的方法
- hdu 2141 Can you find it?
- 5 网络层----IP协议相关技术
- 算法之递推及其应用(递推关系的建立及在信息学竞赛中的应用 安徽 高寒蕊)...
- 学习Spring Boot:(五)使用 devtools热部署
- toj 4317 多连块拼图
- CSS3 弹性盒子模型
- hiprint使用初体验,模板设计经验分享
- matlab学习笔记(4)
- iOS网络协议_HTTP/TCP/IP浅析
- JDK源码学习系列07----Stack
- 怎么解决微信屏蔽app下载链接
- 20220609 C++版的ends_with
- Git连接GitHub仓库,同步上传图片及CSDN外链图片转存失败解决方案
- Qt植物大战僵尸实现修改阳光和无冷却
- C语言:L1-039 古风排版 (20 分)
- 陈凯歌: 大创意大《无极》
- ECU诊断软件设计(1)
- 腾讯/阿里/百度 BAT人才体系的职位层级、薪酬、晋升标准
- 比你聪明的人比你y更聪明
热门文章
- docker管理平台 shipyard安装
- NAPI模式--中断和轮询的折中以及一个负载均衡的问题
- ansible register when: result | succeeded when: item.rc != 0
- 与动态执行的C# 代码进行通讯
- mysql延迟判断模板
- shell脚本中echo显示内容带颜色
- crontab(定时任务操作)
- source insight快捷键及使用技巧
- python常用的字串格式化选项
- 使用git命令导出项目_【git学习】SVN项目迁移到Git操作指南