-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move QR code module to a docker container (#2)
This resolves the issue with zbar and opencv dependencies
- Loading branch information
1 parent
7b1a1b8
commit 471dc61
Showing
11 changed files
with
106 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,2 @@ | ||
pdf2image==1.16.0 | ||
Pillow==9.3.0 | ||
opencv-python==4.8.0.76 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,18 @@ | ||
<div class="col-md-12"> | ||
{% if results %} | ||
<div class="col-md-12"> | ||
<div class="card"> | ||
<div class="header"> | ||
<h4 class="title">QRcode Reader</h4> | ||
<p class="category">Detailed Results</p> | ||
</div> | ||
<div class="content"> | ||
{% if results.urls %} | ||
<label>Extracted Links</label> | ||
<label>Extracted Data</label> | ||
<div class="labeled-content"> | ||
{% for url in results.urls %} | ||
<div>{{url}}</div> | ||
{% for data in results %} | ||
<div>{{data}}</div> | ||
{% endfor %} | ||
</div> | ||
{% endif %} | ||
|
||
{% if results.clean %} | ||
<p>No suspicious object found</p> | ||
{% endif %} | ||
</div> | ||
</div> | ||
</div> | ||
{% endif %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
FROM python:3 | ||
|
||
RUN apt-get update && apt-get install -y libzbar0 | ||
|
||
COPY requirements.txt /app/requirements.txt | ||
|
||
RUN pip install -r /app/requirements.txt | ||
|
||
COPY script.py /app/script.py | ||
|
||
VOLUME ["/data"] | ||
|
||
WORKDIR /data | ||
|
||
ENTRYPOINT ["python", "/app/script.py"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pyzbar==0.1.9 | ||
opencv-python-headless==4.8.0.76 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#!/usr/bin/env python3 | ||
import sys | ||
import cv2 | ||
from pyzbar.pyzbar import decode | ||
|
||
|
||
def main(img): | ||
qrcode_data = set() | ||
|
||
# attempt QR code decoding via opencv | ||
image = cv2.imread(img) | ||
detect = cv2.QRCodeDetector() | ||
try: | ||
retval, decoded, points, straight_qr = detect.detectAndDecodeMulti(image) | ||
if retval: | ||
qrcode_data |= set(decoded) | ||
except cv2.error as e: | ||
pass | ||
|
||
# attempt QR code decoding via zbar | ||
image = cv2.imread(img, 0) | ||
try: | ||
value = decode(image) | ||
qrcode_data |= set([v.data.decode() for v in value]) | ||
except TypeError: | ||
pass | ||
|
||
for data in qrcode_data: | ||
if data.strip(): | ||
print(data.strip()) | ||
|
||
|
||
if __name__ == "__main__": | ||
target_file = sys.argv[1] | ||
main(target_file) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/bin/bash | ||
SCRIPT=`realpath $0` | ||
SCRIPTPATH=`dirname $SCRIPT` | ||
|
||
docker build -t fame/qr_extractor $SCRIPTPATH/docker |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,83 +1,46 @@ | ||
import glob | ||
import pathlib | ||
import hashlib | ||
import pyzbar | ||
|
||
from fame.core.module import ProcessingModule, ModuleInitializationError, ModuleExecutionError | ||
from fame.common.utils import tempdir | ||
|
||
try: | ||
import cv2 | ||
HAVE_CV2 = True | ||
except ImportError: | ||
HAVE_CV2 = False | ||
|
||
try: | ||
from pyzbar.pyzbar import decode | ||
HAVE_PYZBAR = True | ||
except ImportError: | ||
HAVE_PYZBAR = False | ||
from fame.core.module import ProcessingModule, ModuleInitializationError | ||
from ..docker_utils import HAVE_DOCKER, docker_client, docker | ||
import re | ||
|
||
|
||
class QrCodeExtractor(ProcessingModule): | ||
name = "qr_extractor" | ||
description = "Analyze files (via docement preview) to find QRcodes and decode them with two different libs." | ||
acts_on = ["png","jpg","jpeg", "pdf", "word", "html", "excel", "powerpoint"] | ||
triggered_by = "document_preview" | ||
config = [ | ||
{ | ||
"name": "skip_safe_file_review", | ||
"type": "bool", | ||
"default": False, | ||
"description": "Skip file review when no suspicious elements are found." | ||
} | ||
] | ||
description = "find QRcodes in images and decode them" | ||
acts_on = ["png", "jpeg", "bmp", "webp", "avif"] | ||
triggered_by = "*_preview" | ||
config = [] | ||
|
||
# Check that libraries wer loaded correctly | ||
|
||
def initialize(self): | ||
if not HAVE_CV2: | ||
raise ModuleInitializationError(self, "Missing dependency: opencv2") | ||
if not HAVE_PYZBAR: | ||
raise ModuleInitializationError(self, "Missing dependency: pyzbar") | ||
|
||
# For each, check if QRcode is found and extract potentiel URL | ||
# - TO-DO : include document preview for pdf to be able to read the qrcode | ||
# Or trigger the qrcode extractor after document preview | ||
# possibly => mutualize Read image target | ||
# decode QRcode | ||
|
||
def extract_qr_code_by_opencv(img): | ||
image = cv2.imread(img, 0) | ||
try: | ||
detect = cv2.QRCodeDetector() | ||
value, points, straight_qrcode = detect.detectAndDecode(image) | ||
print(value) | ||
return value | ||
except: | ||
return | ||
# Make sure docker is available | ||
if not HAVE_DOCKER: | ||
raise ModuleInitializationError(self, "Missing dependency: docker") | ||
|
||
def parse_output(self, out): | ||
out = out.decode("utf-8", errors="replace") | ||
for line in out.splitlines(): | ||
if re.match("^https?:", line, re.UNICODE | re.IGNORECASE): | ||
self.add_ioc(line) | ||
else: | ||
if not self.results: | ||
self.results = [] | ||
self.results.append(line) | ||
|
||
def each_with_type(self, target, file_type): | ||
if file_type != "url": | ||
try: | ||
self.parse_output( | ||
docker_client.containers.run( | ||
"fame/qr_extractor", | ||
"target.file", | ||
volumes={target: {"bind": "/data/target.file", "mode": "ro"}}, | ||
stderr=True, | ||
remove=True, | ||
) | ||
) | ||
except (docker.errors.ContainerError, docker.errors.APIError) as e: | ||
if hasattr(e, "stderr"): | ||
self.log("error", e.stderr) | ||
elif hasattr(e, "explanation"): | ||
self.log("error", e.explanation) | ||
|
||
def extract_qr_code_by_pyzbar(img): | ||
image = cv2.imread(img, 0) | ||
try: | ||
value = decode(image) | ||
print(value) | ||
return value | ||
except: | ||
return | ||
|
||
def each(self, target): | ||
self.results = {} | ||
|
||
# Get QRcode | ||
self.results[">PYZBAR"] = self.extract_qr_code_by_pyzbar(target) | ||
self.results[">OPENCV"] = self.extract_qr_code_by_opencv(target) | ||
self.add_ioc(results) | ||
#TO-DO add ioc for the url decoded only | ||
#if filetype == "url" and not target.startswith("http"): | ||
# target = "http://{}".format(target) | ||
#if filetype == "url": | ||
# self.add_ioc(target) | ||
return True | ||
|
||
#TO-DO Include call to URL preview |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
opencv-python==4.8.0.76 | ||
pyzbar==0.1.9 | ||
docker==6.1.3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters