Skip to content

Instantly share code, notes, and snippets.

@TheRyanHickman
Created September 15, 2021 18:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheRyanHickman/b15fb30893152b5a9d00eb1a4b34ffec to your computer and use it in GitHub Desktop.
Save TheRyanHickman/b15fb30893152b5a9d00eb1a4b34ffec to your computer and use it in GitHub Desktop.
CV Readme
# Crane-Util-CV2-pipeline
CV2 pipeline for post-processing with Tesserocr
# Installation
You will need OpenCV 2.3.1+ on your computer to use the node wrapper. On Mac you may install using brew:
```
brew tap homebrew/science
brew install opencv@2
brew link --force opencv@2
echo 'export PATH="/usr/local/opt/opencv@2/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile
```
If you still got error like: `ERROR: failed to run: pkg-config`
```
brew install pkg-config
```
After that, run the npm install script:
```
npm install --save
```
Tesseract.js fails to properly download the trained data, so we must get it ourselves. With bash run:
```
./install.sh
```
Or alternatively `npm setup`.
To run tests we use Jest; you can run all tests by running `npm test`. To run a particular test, use the Jest CLI from the root directory:
```
jest tests/cv.test.js
```
# Dockerfile
Before building docker image:
``` bash
wget https://repo.continuum.io/archive/Anaconda3-5.0.1-Linux-x86_64.sh
```
Then:
```
docker build .
```
This takes a long time.
Run:
```
docker run -d -p 3000:3000 <image id>
```
# Start Server
To start the server, ensure everything necessary is installed, and then run `npm start`. Alternatively, you can call the server with node:
```
node index.js
```
To send requests to the server specify an endpoint as well as the port (default is 3000). You can POST data to the endpoints as below:
``` bash
curl --request POST \
--url http://localhost:3000/colors \
--header 'content-type: application/json' \
--data '{
"url": "https://ibin.co/4KRdSJPM7IQF.jpg"
}'
```
# A note on Tesseract
The OCR script allows you to reuse a Tesseract engine, or to create a new one for that call.
Tesseract does not scale linearly with cores. As a result it is actually more efficient to have 2 engines on 4 cores than 1 engine on 4 cores or 1 engine per core. You can read some more about this [on this GitHub issues thread about Tesseract speedup.](https://github.com/tesseract-ocr/tesseract/issues/263)
Our tests indicate 2 cores per engine is the ideal form. As a result we recommend you create 1 engine for use on large images (> 500x500) and 1 engine for use on smaller images, and run them in parallel to maximize a quad-core CPU. It is possible to achieve a greater speedup by optimizing cores and using different buildtime flags for Tesseract when deploying on specific architectures or devices with more than 4 cores, but we do not currently support queuing up jobs to multiple engines.
We do, however, support queuing up jobs to **one** engine through the TesseractJS library. If you make multiple calls to a single engine, `TesseractJob` instances will be created and be queued up to that engine (we can catch these with `await` as they resolve in a Promise-like manner). They will then execute sequentially (it is not possible to batch or asynchronously send requests to a Tesseract engine).
# API Spec
OCR object:
``` JSON
[
{
"crop_path": "local path to crop image (string)",
"bbox": {
"x": "crop x position in px (integer)",
"y": "crop y position in px (integer)",
"width": "crop width in px (integer)",
"height": "crop height in px (integer)",
"area": "area of bbox"
},
"placement": {
"vertical": "vertical orientation ('very-top'|'top'|'mid-top'|'center'|'mid-bottom'|'bottom')",
"horizontal": "horizontal orientation ('left'|'center'|'right')",
"stageArea": "area of larger region (integer)",
"itemArea": "area of crop (integer)",
"origin": {
"x": "crop x position in px (integer)",
"y": "crop y position in px (integer)",
"width": "crop width in px (integer)",
"height": "crop height in px (integer)"
},
"comp": "debug info (string)"
},
"root": "the URL of the CV'ed image on the CDN (string)",
"ocr": [
{
"text": "detected text of the line (string)",
"bbox": {
"x0": "xmin (float)",
"y0": "ymin (float)",
"x1": "xmax (float)",
"y1": "ymax (float)"
},
"confidence": "score (int, 0-100)",
"is_serif": "is font serif (boolean)",
"font_name": "font name (string)",
"font_size": "font size in pt (int)",
"font_id": "font id # (int)",
"in_dictionary": "dictionary word (boolean)"
},
...
]
},
...
]
```
{
"color": "#3865e1",
"name": {
"name": "RoyalBlue",
"hex": "4169e1",
"rgb": "65,105,225",
"distance": 177.65978723391515
}
},
Colors object:
``` JSON
[
{
"color": "hex code for color, starting with a # (string)",
"name": {
"name": "name of color (string)",
"hex": "hex code of this named color (string, no #)",
"rgb": "red,green,blue (comma-delimited numbers)",
"distance": "distance between the actual and detected color in Cartesian RGB space (number)"
}
},
...
]
```
Routes:
## `/pipe` (POST)
### Request:
JSON formatted POST request, must include a "url" key with a valid image (direct link, must end in filetype)
Example:
``` JSON
{
"url": "https://ibin.co/4KRdSJPM7IQF.jpg"
}
```
### Response:
An object containing keys "ocr" and "colors" which contain the individual response objects.
``` JSON
{
"ocr": "OCR object",
"colors": "Colors object"
}
```
## `/colors` (POST)
### Request:
JSON formatted POST request, must include a "url" key with a valid image (direct link, must end in filetype)
Example:
``` JSON
{
"url": "https://ibin.co/4KRdSJPM7IQF.jpg"
}
```
### Response:
A Colors object.
## `/ocr` (POST)
### Request:
JSON formatted POST request, must include a "url" key with a valid image (direct link, must end in filetype)
Example:
``` JSON
{
"url": "https://ibin.co/4KRdSJPM7IQF.jpg"
}
```
## #Response:
An OCR object.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment