{"_id":"js-aruco2","name":"js-aruco2","dist-tags":{"latest":"2.0.0"},"versions":{"2.0.0":{"name":"js-aruco2","version":"2.0.0","description":"JavaScript porting of the ArUco library supporting multiple dictionaries including ARUCO_MIP_36h12 and custom dictionaries for augmented reality marker detection","main":"src/aruco.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/damianofalcioni/js-aruco2.git"},"keywords":["aruco","cv","computer-vision","augmented-reality","ar","marker-detection","opencv","image-processing","qr-code","marker","detection","camera","video","nodejs","browser"],"author":{"name":"Damiano Falcioni"},"license":"MIT","bugs":{"url":"https://github.com/damianofalcioni/js-aruco2/issues"},"homepage":"https://github.com/damianofalcioni/js-aruco2#readme","engines":{"node":">=12.0.0"},"_id":"js-aruco2@2.0.0","gitHead":"0491d5d228746411d0e9dd602b98f48636a644ba","_nodeVersion":"24.1.0","_npmVersion":"11.3.0","dist":{"integrity":"sha512-2R9P7INqIkg1fsGBazSDLChmfwJpbaYN26gO6wFr1TLIOrvwQf0YzuhwVZAPF8frQ4cjdppAN0dRmExEd/6wqw==","shasum":"40edeeb242444b89178ddf6d8a7580470938ad73","tarball":"https://registry.npmjs.org/js-aruco2/-/js-aruco2-2.0.0.tgz","fileCount":28,"unpackedSize":424088,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFuOSHCT6YZDRpDMXjIFcaFwnyKknt9gHLc2vugIAEVqAiBr7oS+AxJei5UK2SsoqaianjHk0fg+zifZgGgw0RI7DQ=="}]},"_npmUser":{"name":"lucas-vitrus","email":"lucas@vitrus.ai","actor":{"name":"lucas-vitrus","email":"lucas@vitrus.ai","type":"user"}},"directories":{},"maintainers":[{"name":"lucas-vitrus","email":"lucas@vitrus.ai"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/js-aruco2_2.0.0_1750313967333_0.3740090301590384"},"_hasShrinkwrap":false}},"time":{"created":"2025-06-19T06:19:27.332Z","2.0.0":"2025-06-19T06:19:27.597Z","modified":"2025-06-19T06:19:27.910Z"},"maintainers":[{"name":"lucas-vitrus","email":"lucas@vitrus.ai"}],"description":"JavaScript porting of the ArUco library supporting multiple dictionaries including ARUCO_MIP_36h12 and custom dictionaries for augmented reality marker detection","homepage":"https://github.com/damianofalcioni/js-aruco2#readme","keywords":["aruco","cv","computer-vision","augmented-reality","ar","marker-detection","opencv","image-processing","qr-code","marker","detection","camera","video","nodejs","browser"],"repository":{"type":"git","url":"git+https://github.com/damianofalcioni/js-aruco2.git"},"author":{"name":"Damiano Falcioni"},"bugs":{"url":"https://github.com/damianofalcioni/js-aruco2/issues"},"license":"MIT","readme":"# JS-ARUCO2\r\n\r\n**js-aruco2** is a fork of [js-aruco](https://github.com/jcmellado/js-aruco) that supports also the ARUCO_MIP_36h12 dictionary and any other ArUco or custom dictionary for square markers. Additionally, this library is ready to be used in NodeJS to recognize markers from FFMPEG video streams and allows to generate markers in SVG format.\r\n\r\n**js-aruco2** is a pure Javascript implementation of [ArUco](https://www.uco.es/investiga/grupos/ava/portfolio/aruco/), a minimal library for Augmented Reality applications based on OpenCv.\r\n\r\n\r\n## Demos\r\n\r\n100% client side JavaScript, running in your browser (see details below):\r\n\r\n- [Webcam live demo! (ARUCO Dictionary)](https://damianofalcioni.github.io/js-aruco2/samples/getusermedia/getusermedia_ARUCO.html)\r\n\r\n- [Webcam live demo! (ARUCO_MIP_36h12 Dictionary)](https://damianofalcioni.github.io/js-aruco2/samples/getusermedia/getusermedia_ARUCO_MIP_36h12.html)\r\n\r\n- [Visual debugging live demo (ARUCO_MIP_36h12 Dictionary)!](https://damianofalcioni.github.io/js-aruco2/samples/debug/debug.html)\r\n\r\n- [3D Earth (ARUCO_MIP_36h12 Dictionary)!](https://damianofalcioni.github.io/js-aruco2/samples/debug-posit/debug-posit.html)\r\n\r\n- [Markers Creator](https://damianofalcioni.github.io/js-aruco2/samples/marker-creator/marker-creator.html)\r\n\r\n## Markers \r\n\r\nA square grid with an external unused black border. Internal cells contains id information.\r\n\r\nThe markes are recognized using the dictionary specified. The library currently support the following dictionaries:\r\n- ARUCO: 7x7 Marker with 25 bit information, minimum hamming distance between any two codes = 3 and 1023 codes. [Create ARUCO Markers](https://damianofalcioni.github.io/js-aruco2/samples/marker-creator/marker-creator.html?dictionary=ARUCO).\r\n- [ARUCO_MIP_36h12](https://sourceforge.net/projects/aruco/files/aruco_mip_36h12_dict.zip/download): 8x8 Marker with 36 bit information, minimum hamming distance between any two codes = 12 and 250 codes. [Create ARUCO_MIP_36h12 Markers](https://damianofalcioni.github.io/js-aruco2/samples/marker-creator/marker-creator.html?dictionary=ARUCO_MIP_36h12).\r\n\r\n- AprilTag, ARTag, ARToolkitPlus, ChiliTags, and other ArUco additionals dictionaries are available in the [dictionaries folder](./src/dictionaries/).\r\n\r\nThe library can be anyway easily adapted to work with any other ArUco dictionary for square markers. \r\n\r\n## Usage\r\nCreate an `AR.Detector` object using default ARUCO_MIP_36h12 dictionary:\r\n\r\n```\r\nvar detector = new AR.Detector();\r\n```\r\nCreate an `AR.Detector` object using a specific dictionary (dictionaries available out of the box in the library are 'ARUCO' and 'ARUCO_MIP_36h12'):\r\n\r\n```\r\nvar detector = new AR.Detector({\r\n  dictionaryName: 'ARUCO'\r\n});\r\n```\r\n\r\nAdditionally, is possible to specify a custom hamming distance for the specified dictionary:\r\n\r\n```\r\nvar detector = new AR.Detector({\r\n  dictionaryName: 'ARUCO_MIP_36h12',\r\n  maxHammingDistance: 5\r\n});\r\n```\r\n\r\nIn the previous sample, the default maximum allowed hamming distance of the dictionary ARUCO_MIP_36h12 (that is 12) is replaced with 5. Doing so will be identified only markers with a detection error below 5, making the detection more reliable in case of high resolution images, at the cost of skipping possibles relevant markers in low resolution images.\r\n\r\n### Markers detection on Canvas images\r\nCall `detect` function with imageData parameter:\r\n\r\n```\r\nvar markers = detector.detect(imageData);\r\n```\r\n\r\n`markers` result will be an array of `AR.Marker` objects with detected markers.\r\n\r\n`AR.Marker` objects have two properties:\r\n\r\n * `id`: Marker id.\r\n * `corners`: 2D marker corners.\r\n\r\n`imageData` argument must be a valid `ImageData` canvas object.\r\n\r\n```\r\nvar canvas = document.getElementById(\"canvas\");\r\n    \r\nvar context = canvas.getContext(\"2d\");\r\n\r\nvar imageData = context.getImageData(0, 0, width, height);\r\n```\r\n\r\n### Markers detection on RGBA Raw images\r\nCall `detect` function with width, height and data parameters:\r\n\r\n```\r\nvar markers = detector.detect(width, height, data);\r\n```\r\n`width` and `height` must be integer numbers representing the image size.\r\n`data` must be an 8-bit unsigned `ArrayBuffer` (eg. `Uint8ClampedArray`) containing the sequence of RGBA image bytes (R, G, B, A, R, G, B, A, R, G, B, A, ....).\r\n\r\n\r\n### Markers detection on RGBA video stream\r\nInitialize the stream detection calling the `detectStreamInit` function with width, height and callback parameters:\r\n\r\n```\r\ndetector.detectStreamInit(width, height, callback);\r\n```\r\n`width` and `height` must be integer numbers representing the size of video image.\r\n`callback` must be a function that accept two parameters: the first is the image processed and the second the markers list detected\r\n\r\n```\r\nvar callback = function (image, markerList) {\r\n  console.log(markerList);\r\n};\r\n```\r\n\r\nThe callback function will be called every time an image in the video stream is processed, providing the markers detection results.\r\n\r\nAfter this initialization phase, the function detectStream must be called every time a video chunk is available (the function accept chunks of every size):\r\n\r\n```\r\ndetector.detectStream(data);\r\n```\r\n`data` must be an 8-bit unsigned `ArrayBuffer` (eg. `Uint8ClampedArray`) containing a video chunk as sequence of RGBA image bytes (R, G, B, A, R, G, B, A, R, G, B, A, ....). \r\n\r\n\r\n## Markers Detection in NodeJS \r\nAn example of server side detection in NodeJS using stream data from FFMPEG stream is available in the [samples/node-js-server](./samples/node-js-server) folder.\r\n\r\n\r\n## Creation of Custom Dictionaries\r\nCustom dictionaries can be added to the library, editing the AR.DICTIONARIES before the instansiation of the ArUco Detector:\r\n\r\n```\r\n//example of custom dictionary\r\nAR.DICTIONARIES.MyDictionary = {\r\n  nBits: 25,\r\n  tau: 1,\r\n  codeList: ['0x1084210UL', '0x1084217UL', ...]\r\n};\r\n```\r\n`nBits` must contain the bit dimension of the markers in your dictionary.\r\n`tau` can contain the hamming distance of the codes in your dictionary (optional).\r\n`codeList` must be an array of strings containing the hexadecimal representation of every marker in your dictionary. The order is important because the position in the array represents the marker id.\r\n\r\nThe defined dictionary is then available to the detector:\r\n\r\n```\r\nvar detector = new AR.Detector({\r\n  dictionaryName: 'MyDictionary'\r\n});\r\n```\r\n\r\n## Creation of Marker SVG image\r\nCreate a `AR.Dictionary` object providing as parameter the dictionary name to use (currently available dictionaries are 'ARUCO' and 'ARUCO_MIP_36h12') and then call the function `generateSVG` providing as parameter the id to generate (that is a number between 0 and the size-1 of the `codeList` array in the specified dictionary):\r\n```\r\nvar dictionary = new AR.Dictionary('ARUCO');\r\nvar SVG = dictionary.generateSVG(0);\r\n```\r\nA [sample page](https://damianofalcioni.github.io/js-aruco2/samples/marker-creator/marker-creator.html) is available to show this feature.\r\n\r\n## 3D Pose Estimation\r\nCreate an `POS.Posit` object:\r\n\r\n```\r\nvar posit = new POS.Posit(modelSize, canvas.width);\r\n```\r\n\r\n`modelSize` argument must be the real marker size (millimeters).\r\n\r\nCall `pose` function:\r\n\r\n```\r\nvar pose = posit.pose(corners);\r\n```\r\n\r\n`corners` must be centered on canvas:\r\n\r\n```\r\nvar corners = marker.corners;\r\n\r\nfor (var i = 0; i < corners.length; ++ i){\r\n  var corner = corners[i];\r\n\r\n  corner.x = corner.x - (canvas.width / 2);\r\n  corner.y = (canvas.height / 2) - corner.y;\r\n}\r\n```\r\n\r\n`pose` result will be a `POS.Pose` object with two estimated poses (if any):\r\n\r\n * `bestError`: Error of the best estimated pose.\r\n * `bestRotation`: 3x3 rotation matrix of the best estimated pose.\r\n * `bestTranslation`: Translation vector of the best estimated pose.\r\n * `alternativeError`: Error of the alternative estimated pose.\r\n * `alternativeRotation`: 3x3 rotation matrix of the alternative estimated pose.\r\n * `alternativeTranslation`: Translation vector of the alternative estimated pose.\r\n\r\nNote: POS namespace can be taken from posit1.js or posit2.js.\r\n\r\n## Support Me <3\r\n[![Buy me a coffee](https://user-images.githubusercontent.com/8982949/109154198-40129680-776e-11eb-8015-67da5a4c78d1.png)](https://www.paypal.me/damianofalcioni/0.99)\r\n","readmeFilename":"README.md","_rev":"1-cd31121709ea66566384c2911fdf4df4"}