diff --git a/cmake_install.js b/cmake_install.js index 8fda04e..aee98c6 100644 --- a/cmake_install.js +++ b/cmake_install.js @@ -3,6 +3,7 @@ var https = require('https'); var fs = require('fs'); var tar = require('tar'); var child_process = require('child_process'); +var http = require('http'); function onError(err) { console.error('An error occurred:', err) @@ -33,6 +34,8 @@ function downloadAndRun(filename, type, folder, url) { var tmpFilePath = filename + "." + type; + console.log(url); + https.get(url, function(response) { response.on('data', function (data) { fs.appendFileSync(tmpFilePath, data) @@ -43,9 +46,9 @@ function downloadAndRun(filename, type, folder, url) { var zip = new AdmZip(tmpFilePath); zip.extractAllTo("./"); - fs.unlink(tmpFilePath); + //fs.unlink(tmpFilePath); fs.renameSync('./' + folder, './cmake_binary'); - runCmakeJS('.\\node_modules\\.bin\\cmake-js.cmd', 'cmake.exe', '\\'); + runCmakeJS('cmake-js', 'cmake.exe', '\\'); } else if(type == "tar.gz") { @@ -53,7 +56,7 @@ function downloadAndRun(filename, type, folder, url) ls.stdout.on("end", function() { fs.unlink(tmpFilePath); fs.renameSync('./' + folder, './cmake_binary'); - runCmakeJS('./node_modules/cmake-js/bin/cmake-js', 'cmake', '/'); + runCmakeJS('cmake-js', 'cmake', '/'); }); } else diff --git a/example.js b/example.js index bfdafed..68f9582 100644 --- a/example.js +++ b/example.js @@ -1,8 +1,16 @@ 'use strict'; var sceneText = require('bindings')('node_text_detector'); var util = require('util'); +var fs = require('fs'); var result; console.log('-----------------------------------------------------'); -result = sceneText.GetTextSync('sample_images/3.jpg', __dirname); -console.log(util.inspect(result, {depth: 9, colors: true})); \ No newline at end of file +fs.readFile('./sample_images/3.jpg', function(error, data) { + if (!error) { + var result = sceneText.GetTextSync(data, __dirname, '0123456789ABCDEFGHJKLMNPRSTUVWXYZ'); + console.log(util.inspect(result, {depth: 9, colors: true})); + } else { + console.log('Load Image from Path failed'); + return undefined; + } +}); \ No newline at end of file diff --git a/package.json b/package.json index 1a518a7..11c6568 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "bindings":"latest" }, "scripts": { - "install": "node cmake_install.js", + "install": "npm install -g cmake-js && node cmake_install.js", "test" : "node example.js" } } diff --git a/sample_images/3.jpg b/sample_images/3.jpg index 3aa0223..8ff8e1e 100644 Binary files a/sample_images/3.jpg and b/sample_images/3.jpg differ diff --git a/src/ocr/ocr.cpp b/src/ocr/ocr.cpp index 1d62bf8..a844829 100644 --- a/src/ocr/ocr.cpp +++ b/src/ocr/ocr.cpp @@ -42,20 +42,6 @@ class Regions{ vector< vector > region_groups; }; -class decodedTxtRegion{ - public: - int x1,x2,y1,y2; - vector words; - vector confidences; -}; - -class outputOCR{ - public: - int x1,x2,y1,y2; - vector decodedText; - -}; - Rect groups_draw(Mat &src, vector &groups); void er_show(vector &channels, vector > ®ions); @@ -64,14 +50,14 @@ void er_draw(vector &channels, vector > ®ions, vector computeGroupsWithMinArea(Mat &src,vector &channels,float minArea); -vector doOCR(string languageFile, Mat &image,vector channels,vector > regions,vector< vector > nm_region_groups,vector nm_boxes); +vector doOCR(string languageFile, string whitelist, Mat &image,vector channels,vector > regions,vector< vector > nm_region_groups,vector nm_boxes); Regions computeRegionGroups(Mat &src,vector &channels,float minArea); -OutputOCR detectAndDecode(string languageFile, Mat &src); - +OutputOCR detectAndDecode(string languageFile, string whitelist, Mat &src); -outputOCR Ocr(string path,Rect box) { +/* +OutputOCR Ocr(string path,Rect box) { // namedWindow("grouping",WINDOW_NORMAL); // read the image Mat src = imread(path); @@ -111,9 +97,9 @@ outputOCR Ocr(string path,Rect box) { outputOCR output; output.decodedText=decodedTxtRegions; return output; -} +}*/ -OutputOCR* Ocr(char* buffer, unsigned int len, string languageFile) +OutputOCR* Ocr(char* buffer, unsigned int len, string languageFile, string whitelist) { Mat temp(1, len, CV_8UC3, buffer); Mat src = imdecode(temp, 1); @@ -122,10 +108,10 @@ OutputOCR* Ocr(char* buffer, unsigned int len, string languageFile) LOG << "Unable to load image." << endl; return NULL; } - return new OutputOCR(detectAndDecode(languageFile, src)); + return new OutputOCR(detectAndDecode(languageFile, whitelist, src)); } -OutputOCR* Ocr (string path, string languageFile) { +OutputOCR* Ocr (string path, string languageFile, string whitelist) { // namedWindow("grouping",WINDOW_NORMAL); //Mat src = imread(path); char* buffer = NULL; @@ -158,10 +144,10 @@ OutputOCR* Ocr (string path, string languageFile) { LOG << src.type() << endl; LOG << CV_8UC3 << endl; LOG << "image loaded" << endl; - return new OutputOCR(detectAndDecode(languageFile, src)); + return new OutputOCR(detectAndDecode(languageFile, whitelist, src)); } -OutputOCR detectAndDecode(string languageFile, Mat &src){ +OutputOCR detectAndDecode(string languageFile, string whitelist, Mat &src){ // Extract channels to be processed individually vector channels; @@ -188,7 +174,7 @@ OutputOCR detectAndDecode(string languageFile, Mat &src){ // draw groups Rect group_box= groups_draw(src, groups_boxes); imwrite("save.jpg",src); - vector decodedTxt=doOCR(languageFile, src,channels,region.regions,region.region_groups,groups_boxes); + vector decodedTxt=doOCR(languageFile, whitelist, src,channels,region.regions,region.region_groups,groups_boxes); OutputOCR output(Box(group_box.tl().x, group_box.br().x, group_box.tl().y, group_box.br().y), decodedTxt); @@ -200,11 +186,11 @@ OutputOCR detectAndDecode(string languageFile, Mat &src){ } return output; } -vector doOCR(string languageFile, Mat &image,vector channels,vector > regions,vector< vector > nm_region_groups,vector nm_boxes){ +vector doOCR(string languageFile, string whitelist, Mat &image,vector channels,vector > regions,vector< vector > nm_region_groups,vector nm_boxes){ // Text Recognition (OCR) double t_r = (double)getTickCount(); - Ptr ocr = OCRTesseract::create(languageFile.c_str()); + Ptr ocr = OCRTesseract::create(languageFile.c_str(), NULL, whitelist.c_str()); string output; Mat out_img; Mat out_img_detection; @@ -236,10 +222,19 @@ vector doOCR(string languageFile, Mat &image,vector channels,v vector confidences; ocr->run(group_img, output, &boxes, &words, &confidences, OCR_LEVEL_WORD); + string word = ""; + for(auto it = words.begin();it != words.end();it++) + word += *it; + float confidence = 0; + for(auto it = confidences.begin();it != confidences.end();it++) + if(*it > confidence) + confidence = *it; + output.erase(remove(output.begin(), output.end(), '\n'), output.end()); - LOG << "OCR output = \"" << output << "\" length = " << output.size() << endl; + LOG << "OCR output = \"" << output << "\" length = " << output.size() << " confidence = " << confidence << endl; - decodedTxtRegions.push_back(DecodedText(Box(nm_boxes[i].tl().x, nm_boxes[i].br().x, nm_boxes[i].tl().y, nm_boxes[i].br().y), words, confidences)); + if(words.size() != 0) + decodedTxtRegions.push_back(DecodedText(Box(nm_boxes[i].tl().x, nm_boxes[i].br().x, nm_boxes[i].tl().y, nm_boxes[i].br().y), word, confidence)); } return decodedTxtRegions; } @@ -371,13 +366,3 @@ void er_draw(vector &channels, vector > ®ions, vector 1){ - //detectRegions = To(info[1]).FromJust(); + OutputOCR* decodedText = NULL; + if(!node::Buffer::HasInstance(info[0])) + { + // get the value of path + Utf8String *utfPath = new Utf8String(info[0]); + Utf8String *utfLanguageFile = new Utf8String(info[1]); + Utf8String *utfWhitelist = new Utf8String(info[2]); + string path(**utfPath); + string languageFile(**utfLanguageFile); + string whitelist(**utfWhitelist); + + decodedText = Ocr(path, languageFile, whitelist); } - // call the decoder here - OutputOCR* decodedText = Ocr(path, languageFile); + else + { + char* image = (char*)node::Buffer::Data(info[0]->ToObject()); + unsigned int len = node::Buffer::Length(info[0]->ToObject()); + Utf8String *utfLanguageFile = new Utf8String(info[1]); + Utf8String *utfWhitelist = new Utf8String(info[2]); + string languageFile(**utfLanguageFile); + string whitelist(**utfWhitelist); + + decodedText = Ocr(image, len, languageFile, whitelist); + } + if(decodedText == NULL) - info.GetReturnValue().Set(Nan::New()); + info.GetReturnValue().Set(Nan::Undefined()); else info.GetReturnValue().Set(Nan::New(decodedText->ToLocal())); + delete decodedText; } diff --git a/src/util/decoded_text.hpp b/src/util/decoded_text.hpp index f9b7446..4dedbd5 100644 --- a/src/util/decoded_text.hpp +++ b/src/util/decoded_text.hpp @@ -10,34 +10,22 @@ struct DecodedText { - DecodedText(Box box, std::vector words, std::vector confs) - : box(box), words(words), confs(confs) {} + DecodedText(Box box, std::string word, float conf) + : box(box), word(word), conf(conf) {} Box box; - std::vector words; - std::vector confs; + std::string word; + float conf; v8::Local object; v8::Local ToLocal() { v8::Local l_box = box.ToLocal(); - v8::Local l_words = Nan::New(); - v8::Local l_confs = Nan::New(); - - for(int i = 0;i < words.size();i++) - { - Nan::Set(l_words, i, Nan::New(words[i]).ToLocalChecked()); - } - - for(int i=0;i out = Nan::New(); Nan::Set(out, Nan::New("box").ToLocalChecked(), l_box); - Nan::Set(out, Nan::New("words").ToLocalChecked(), l_words); - Nan::Set(out, Nan::New("confidences").ToLocalChecked(), l_confs); + Nan::Set(out, Nan::New("value").ToLocalChecked(), Nan::New(word.c_str()).ToLocalChecked()); + Nan::Set(out, Nan::New("confidence").ToLocalChecked(), Nan::New(conf)); return out; } };