## NBIS-rs
[](https://github.com/Seventh-Sense-Artificial-Intelligence/nbis-rs/actions/workflows/ci.yaml)
This is a Rust/Python binding to the NIST Biometric Image Software (NBIS) library, which is used for processing biometric images, particularly in the context of fingerprint recognition.
## Features
- Bindings to NBIS functions for minutia extraction, and matching
- Exports minutiae templates in ISO/IEC 19794-2:2005 format
- Matches minutiae templates against each other using the NBIS Bozorth3 algorithm
## Installation (Rust)
To use NBIS-rs, add the following to your `Cargo.toml`:
```toml
[dependencies]
nbis = "0.1.2"
```
## Usage (Rust)
Here's a simple example of how to use NBIS-rs in your project:
```rust
fn main() -> Result<(), Box<dyn std::error::Error>> {
use nbis;
use nbis::Minutiae;
// Read the bytes from a file (you could also use nbis::extract_minutiae_from_image_file)
// but here we just load the image bytes as image paths on mobile platforms can be tricky.
let image_bytes = std::fs::read("test_data/p1/p1_1.png")?;
let minutiae_1 = nbis::extract_minutiae(&image_bytes, None)?;
let image_bytes = std::fs::read("test_data/p1/p1_2.png")?;
let minutiae_2 = nbis::extract_minutiae(&image_bytes, None)?;
let image_bytes = std::fs::read("test_data/p1/p1_3.png")?;
let minutiae_3 = nbis::extract_minutiae(&image_bytes, None)?;
// Compare the two sets of minutiae
let score = minutiae_1.compare(&minutiae_2);
assert!(score > 50, "Expected a high similarity score between p1_1 and p1_2");
let score = minutiae_1.compare(&minutiae_3);
assert!(score > 50, "Expected a high similarity score between p1_1 and p1_3");
let score = minutiae_2.compare(&minutiae_3);
assert!(score > 50, "Expected a high similarity score between p1_2 and p1_3");
// Next we will demonstrate conversion to ISO/IEC 19794-2:2005 format
// and back to a `Minutiae` object.
// First, convert the minutiae to ISO template bytes
let iso_template: Vec<u8> = minutiae_1.to_iso_19794_2_2005();
// And load it back
let minutiae_from_iso = nbis::load_iso_19794_2_2005(&iso_template)?;
// Compare the original minutiae with the one loaded from ISO template
for (a, b) in minutiae_from_iso.get().iter().zip(minutiae_1.get().iter()) {
assert_eq!(a.x(), b.x());
assert_eq!(a.y(), b.y());
assert_eq!(a.angle(), b.angle());
assert_eq!(a.kind(), b.kind());
// Reliability is quantized in the round-trip conversion,
// so we allow a small margin of error.
assert!((a.reliability() - b.reliability()).abs() < 1e-1);
}
// Finally we demonstrate loading from a file and comparing a negative match
let minutiae_4 = nbis::extract_minutiae_from_image_file("test_data/p2/p2_1.png", None)?;
let score = minutiae_1.compare(&minutiae_4);
assert!(score < 50, "Expected a low similarity score between p1_1 and p2_1");
Ok(())
}
```
## Installation (Python)
To install the Python bindings, you can use pip:
```bash
pip install nbis-py
```
## Usage (Python)
Here's a simple example of how to use the NBIS Python bindings:
```python
import nbis
# Read the bytes from a file
image_bytes = open("test_data/p1/p1_1.png", "rb").read()
minutiae_1 = nbis.extract_minutiae(image=image_bytes, ppi=None)
image_bytes = open("test_data/p1/p1_2.png", "rb").read()
minutiae_2 = nbis.extract_minutiae(image=image_bytes, ppi=None)
image_bytes = open("test_data/p1/p1_3.png", "rb").read()
minutiae_3 = nbis.extract_minutiae(image=image_bytes, ppi=None)
# Compare the two sets of minutiae
score = minutiae_1.compare(minutiae_2)
assert score > 50, "Expected a high similarity score between p1_1 and p1_2"
score = minutiae_1.compare(minutiae_3)
assert score > 50, "Expected a high similarity score between p1_1 and p1_3"
score = minutiae_2.compare(minutiae_3)
assert score > 50, "Expected a high similarity score between p1_2 and p1_3"
# Convert minutiae to ISO/IEC 19794-2:2005 format
iso_template = minutiae_1.to_iso_19794_2_2005()
# Load it back
minutiae_from_iso = nbis.load_iso_19794_2_2005(iso_template)
# Compare the original minutiae with the one loaded from ISO template
for a, b in zip(minutiae_from_iso.get(), minutiae_1.get()):
assert a.x() == b.x()
assert a.y() == b.y()
assert a.angle() == b.angle()
assert a.kind() == b.kind()
# Reliability is quantized in the round-trip conversion,
# so we allow a small margin of error.
assert abs(a.reliability() - b.reliability()) < 0.1
# Finally we demonstrate loading from a file and comparing a negative match
minutiae_4 = nbis.extract_minutiae_from_image_file("test_data/p2/p2_1.png", ppi=None)
score = minutiae_1.compare(minutiae_4)
assert score < 50, "Expected a low similarity score between p1_1 and p2_1"
```
## Contributing
Contributions are welcome! Please open an issue or submit a pull request on GitHub.
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
Raw data
{
"_id": null,
"home_page": "https://github.com/Seventh-Sense-Artificial-Intelligence/nbis-rs",
"name": "nbis-py",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "fingerprint, nbis, biometrics, rust, uniffi",
"author": "Varun Chatterji <varun@seventhsense.ai>",
"author_email": "Varun Chatterji <varun@seventhsense.ai>",
"download_url": null,
"platform": null,
"description": "## NBIS-rs\n\n[](https://github.com/Seventh-Sense-Artificial-Intelligence/nbis-rs/actions/workflows/ci.yaml)\n\nThis is a Rust/Python binding to the NIST Biometric Image Software (NBIS) library, which is used for processing biometric images, particularly in the context of fingerprint recognition.\n\n## Features\n\n- Bindings to NBIS functions for minutia extraction, and matching\n- Exports minutiae templates in ISO/IEC 19794-2:2005 format\n- Matches minutiae templates against each other using the NBIS Bozorth3 algorithm\n\n## Installation (Rust)\n\nTo use NBIS-rs, add the following to your `Cargo.toml`:\n\n```toml\n[dependencies]\nnbis = \"0.1.2\"\n```\n\n## Usage (Rust)\n\nHere's a simple example of how to use NBIS-rs in your project:\n\n```rust\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n use nbis;\n use nbis::Minutiae;\n\n // Read the bytes from a file (you could also use nbis::extract_minutiae_from_image_file)\n // but here we just load the image bytes as image paths on mobile platforms can be tricky.\n let image_bytes = std::fs::read(\"test_data/p1/p1_1.png\")?;\n let minutiae_1 = nbis::extract_minutiae(&image_bytes, None)?;\n\n let image_bytes = std::fs::read(\"test_data/p1/p1_2.png\")?;\n let minutiae_2 = nbis::extract_minutiae(&image_bytes, None)?;\n\n let image_bytes = std::fs::read(\"test_data/p1/p1_3.png\")?;\n let minutiae_3 = nbis::extract_minutiae(&image_bytes, None)?;\n\n // Compare the two sets of minutiae\n let score = minutiae_1.compare(&minutiae_2);\n assert!(score > 50, \"Expected a high similarity score between p1_1 and p1_2\");\n let score = minutiae_1.compare(&minutiae_3);\n assert!(score > 50, \"Expected a high similarity score between p1_1 and p1_3\");\n let score = minutiae_2.compare(&minutiae_3);\n assert!(score > 50, \"Expected a high similarity score between p1_2 and p1_3\");\n\n // Next we will demonstrate conversion to ISO/IEC 19794-2:2005 format\n // and back to a `Minutiae` object.\n // First, convert the minutiae to ISO template bytes\n let iso_template: Vec<u8> = minutiae_1.to_iso_19794_2_2005();\n // And load it back\n let minutiae_from_iso = nbis::load_iso_19794_2_2005(&iso_template)?;\n // Compare the original minutiae with the one loaded from ISO template\n for (a, b) in minutiae_from_iso.get().iter().zip(minutiae_1.get().iter()) {\n assert_eq!(a.x(), b.x());\n assert_eq!(a.y(), b.y());\n assert_eq!(a.angle(), b.angle());\n assert_eq!(a.kind(), b.kind());\n // Reliability is quantized in the round-trip conversion,\n // so we allow a small margin of error.\n assert!((a.reliability() - b.reliability()).abs() < 1e-1);\n }\n\n // Finally we demonstrate loading from a file and comparing a negative match\n let minutiae_4 = nbis::extract_minutiae_from_image_file(\"test_data/p2/p2_1.png\", None)?;\n let score = minutiae_1.compare(&minutiae_4);\n assert!(score < 50, \"Expected a low similarity score between p1_1 and p2_1\");\n\n Ok(())\n}\n```\n\n## Installation (Python)\nTo install the Python bindings, you can use pip:\n\n```bash\npip install nbis-py\n```\n\n## Usage (Python)\n\nHere's a simple example of how to use the NBIS Python bindings:\n\n```python\nimport nbis\n\n# Read the bytes from a file\nimage_bytes = open(\"test_data/p1/p1_1.png\", \"rb\").read()\nminutiae_1 = nbis.extract_minutiae(image=image_bytes, ppi=None)\nimage_bytes = open(\"test_data/p1/p1_2.png\", \"rb\").read()\nminutiae_2 = nbis.extract_minutiae(image=image_bytes, ppi=None)\nimage_bytes = open(\"test_data/p1/p1_3.png\", \"rb\").read()\nminutiae_3 = nbis.extract_minutiae(image=image_bytes, ppi=None)\n\n# Compare the two sets of minutiae\nscore = minutiae_1.compare(minutiae_2)\nassert score > 50, \"Expected a high similarity score between p1_1 and p1_2\"\nscore = minutiae_1.compare(minutiae_3)\nassert score > 50, \"Expected a high similarity score between p1_1 and p1_3\"\nscore = minutiae_2.compare(minutiae_3)\nassert score > 50, \"Expected a high similarity score between p1_2 and p1_3\"\n\n# Convert minutiae to ISO/IEC 19794-2:2005 format\niso_template = minutiae_1.to_iso_19794_2_2005()\n# Load it back\nminutiae_from_iso = nbis.load_iso_19794_2_2005(iso_template)\n# Compare the original minutiae with the one loaded from ISO template\nfor a, b in zip(minutiae_from_iso.get(), minutiae_1.get()):\n assert a.x() == b.x()\n assert a.y() == b.y()\n assert a.angle() == b.angle()\n assert a.kind() == b.kind()\n # Reliability is quantized in the round-trip conversion,\n # so we allow a small margin of error.\n assert abs(a.reliability() - b.reliability()) < 0.1\n\n# Finally we demonstrate loading from a file and comparing a negative match\nminutiae_4 = nbis.extract_minutiae_from_image_file(\"test_data/p2/p2_1.png\", ppi=None)\nscore = minutiae_1.compare(minutiae_4)\nassert score < 50, \"Expected a low similarity score between p1_1 and p2_1\"\n```\n\n## Contributing\n\nContributions are welcome! Please open an issue or submit a pull request on GitHub.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Python bindings for NBIS fingerprint processing using Rust + UniFFI",
"version": "0.1.2",
"project_urls": {
"Homepage": "https://github.com/Seventh-Sense-Artificial-Intelligence/nbis-rs",
"Repository": "https://github.com/Seventh-Sense-Artificial-Intelligence/nbis-rs"
},
"split_keywords": [
"fingerprint",
" nbis",
" biometrics",
" rust",
" uniffi"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "14b265b4c688fb589f94d29259a516119f049b2b4e0d4b0ed86a8a7c5269c398",
"md5": "4b2ead574e09541fdd4553bcbaa6a06b",
"sha256": "16f85781a8a85d21868937e132d9f66a67db83ed9651b70c6a1fb68f7a1479a6"
},
"downloads": -1,
"filename": "nbis_py-0.1.2-py3-none-macosx_11_0_arm64.whl",
"has_sig": false,
"md5_digest": "4b2ead574e09541fdd4553bcbaa6a06b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 1041351,
"upload_time": "2025-07-15T19:24:36",
"upload_time_iso_8601": "2025-07-15T19:24:36.765640Z",
"url": "https://files.pythonhosted.org/packages/14/b2/65b4c688fb589f94d29259a516119f049b2b4e0d4b0ed86a8a7c5269c398/nbis_py-0.1.2-py3-none-macosx_11_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "8ff0be56ff1bd707deb83b22f2b660a5f123e9476ba4d2f05da87709f55a1c6d",
"md5": "d529c2124e5870cd203a3e966dea2846",
"sha256": "ccc61cfe7405d996ab46f30279f981ea3ed55cee93a284874cdcb5ca15ee645d"
},
"downloads": -1,
"filename": "nbis_py-0.1.2-py3-none-manylinux_2_34_x86_64.whl",
"has_sig": false,
"md5_digest": "d529c2124e5870cd203a3e966dea2846",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 1170687,
"upload_time": "2025-07-15T19:24:38",
"upload_time_iso_8601": "2025-07-15T19:24:38.509800Z",
"url": "https://files.pythonhosted.org/packages/8f/f0/be56ff1bd707deb83b22f2b660a5f123e9476ba4d2f05da87709f55a1c6d/nbis_py-0.1.2-py3-none-manylinux_2_34_x86_64.whl",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-15 19:24:36",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Seventh-Sense-Artificial-Intelligence",
"github_project": "nbis-rs",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "nbis-py"
}