Skip to content

Commit 3feaba0

Browse files
committed
Merge branch 'dev'
2 parents f91a3cc + 87841a3 commit 3feaba0

File tree

25 files changed

+2662
-178
lines changed

25 files changed

+2662
-178
lines changed

.github/ISSUE_TEMPLATE/new-dojo-template.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,8 @@ assignees: ''
1515

1616
---
1717

18-
![Python](https://img.shields.io/badge/Python-512BD4?style=flat&logo=python&logoColor=yellow)
19-
![JEDI Incolume](https://img.shields.io/badge/incolume-JEDI-blue?style=flat)
20-
![PyCharm](https://img.shields.io/badge/PyCharm-AABBCC?style=flat)
21-
![VS Code](https://img.shields.io/badge/VScode-AABBCC?style=flat&logo=visualstudiocode&logoColor=white)
22-
![VS Code](https://img.shields.io/badge/CodeSpace-AABBCC?style=flat&logo=visualstudiocode&logoColor=white)
18+
![Python](https://img.shields.io/badge/Python-512BD4?style=flat&logo=python&logoColor=yellow) ![JEDI Incolume](https://img.shields.io/badge/incolume-JEDI-blue?style=flat)
19+
[![GitHub release](https://img.shields.io/github/v/release/incolume-jedi/coding-dojo?logo=github&logoColor=white)](https://github.com/incolume-jedi/coding-dojo/releases/latest) ![PyCharm](https://img.shields.io/badge/PyCharm-AABBCC?style=flat) ![VS Code](https://img.shields.io/badge/VScode-AABBCC?style=flat&logo=visualstudiocode&logoColor=white) ![VS Code](https://img.shields.io/badge/CodeSpace-AABBCC?style=flat&logo=visualstudiocode&logoColor=white)
2320

2421
---
2522

@@ -31,14 +28,14 @@ Descrição/apresentação do problema.
3128

3229
## Exemplos
3330

34-
<details>
35-
<summary>Spoiler?</summary>
31+
<details>
32+
<summary>Spoiler?</summary>
3633
Considerar em caso de fatoração:
3734

3835
> modo pythônico
39-
> sem condicionais
36+
> sem condicionais
4037
> estruturas performáticas
41-
> redução de complexidade ciclomática
38+
> redução de complexidade ciclomática
4239
> análise assintótica de algoritmos (big O)
4340

4441
</details>
@@ -57,4 +54,4 @@ N/A - Referências para o dojo, o problema ou para elicidações extras.
5754

5855
---
5956

60-
Copyright &copy; **incolume.com.br** since 2010
57+
Copyright &copy; **incolume.com.br** since 2010

.github/workflows/docs_ci_cd.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ jobs:
5959
run: |
6060
git fetch
6161
git tag -d Unreleased
62-
poetry run gcl -r true -u https://github.com/incolume-jedi/coding-dojo/compare docs/about/CHANGELOG.md
62+
poetry run gcl -r -u https://github.com/incolume-jedi/coding-dojo/compare docs/about/CHANGELOG.md
6363
6464
- name: Generate and deploy the documentation
6565
run: |

docs/user_guide/dojos-resolvidos.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@
88

99
---
1010

11-
152 dojos resolvidos
11+
156 dojos resolvidos
1212

1313
---
1414

1515

1616

1717
### 2025
1818

19+
- [Dojo20250114 &#8212; Preprocess Images for Text OCR - Binarization](https://github.com/incolume-jedi/coding-dojo/tree/dev/incolume/py/coding_dojo_jedi/dojo20250114/README.md){:target="_blank"}
20+
- [Dojo20250112 &#8212; Unificar todas as soluções para validação de números primos](https://github.com/incolume-jedi/coding-dojo/tree/dev/incolume/py/coding_dojo_jedi/dojo20250112/README.md){:target="_blank"}
21+
- [Dojo20250110 &#8212; Customizar agregação de funcionalidades com decoradores](https://github.com/incolume-jedi/coding-dojo/tree/dev/incolume/py/coding_dojo_jedi/dojo20250110/README.md){:target="_blank"}
22+
- [Dojo20250106 &#8212; Preprocess Images for Text OCR - Inverted Images](https://github.com/incolume-jedi/coding-dojo/tree/dev/incolume/py/coding_dojo_jedi/dojo20250106/README.md){:target="_blank"}
1923
- [Dojo20250102 &#8212; Identificar elementos HTML em âncoras no sistema de arquivos](https://github.com/incolume-jedi/coding-dojo/tree/dev/incolume/py/coding_dojo_jedi/dojo20250102/README.md){:target="_blank"}
2024

2125

@@ -186,4 +190,3 @@
186190
---
187191

188192
Copyrigth &copy; **Incolume.com.br** since 2010
189-

incolume/py/coding_dojo_jedi/README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@
88

99
---
1010

11-
152 dojos resolvidos
11+
156 dojos resolvidos
1212

1313
---
1414

15+
- [Dojo20250114 &#8212; Preprocess Images for Text OCR - Binarization](dojo20250114/README.md)
16+
- [Dojo20250112 &#8212; Unificar todas as soluções para validação de números primos](dojo20250112/README.md)
17+
- [Dojo20250110 &#8212; Customizar agregação de funcionalidades com decoradores](dojo20250110/README.md)
18+
- [Dojo20250106 &#8212; Preprocess Images for Text OCR - Inverted Images](dojo20250106/README.md)
1519
- [Dojo20250102 &#8212; Identificar elementos HTML em âncoras no sistema de arquivos](dojo20250102/README.md)
1620
- [Dojo20241224 &#8212; relatório de presidentes brasileiros com foto em formato json](dojo20241224/README.md)
1721
- [Dojo20241221 &#8212; Sum of Subarray Minimums](dojo20241221/README.md)
@@ -166,4 +170,3 @@
166170
---
167171

168172
Copyrigth &copy; **Incolume.com.br** since 2010
169-
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Coding Dojo
2+
3+
**Guilda JEDI Incolume - Grupo Python Incolume**
4+
5+
- _[Seja membro da Guilda JEDI Incolume](https://discord.gg/eBNamXVtBW)_
6+
7+
---
8+
9+
![Python](https://img.shields.io/badge/Python-512BD4?style=flat&logo=python&logoColor=yellow) ![JEDI Incolume](https://img.shields.io/badge/incolume-JEDI-blue?style=flat) ![PyCharm](https://img.shields.io/badge/PyCharm-AABBCC?style=flat) ![VS Code](https://img.shields.io/badge/VScode-AABBCC?style=flat&logo=visualstudiocode&logoColor=white) ![VS Code](https://img.shields.io/badge/CodeSpace-AABBCC?style=flat&logo=visualstudiocode&logoColor=white)
10+
11+
---
12+
13+
## Problema
14+
15+
**Preprocess Images for Text OCR - Inverted Images**
16+
17+
Aplique as técnicas para extração de conteúdo via OCR em Python conforme aplicados no vídeo.
18+
19+
## Exemplos
20+
21+
<details>
22+
<summary>Spoiler?</summary>
23+
Considerar em caso de fatoração:
24+
25+
> modo pythônico
26+
> sem condicionais
27+
> estruturas performáticas
28+
> redução de complexidade ciclomática
29+
> análise assintótica de algoritmos (big O)
30+
31+
</details>
32+
33+
N/A - Exemplos de solução e resposta do problema. Geralmente utilizado para validar os testes do TDD.
34+
35+
## Artefatos
36+
37+
- [dojo](__init__.py)
38+
- [tests](test_20250106.py)
39+
40+
41+
## Referências
42+
- https://youtu.be/ADV-AjAXHdc?si=CcRBcwqwMkninAxQ
43+
- https://github.com/wjbmattingly/ocr_python_textbook/blob/main/02_02_working%20with%20opencv.ipynb
44+
45+
N/A - Referências para o dojo, o problema ou para elicidações extras.
46+
47+
---
48+
49+
Copyright &copy; **incolume.com.br** since 2010
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
"""dojo module.
2+
3+
1. **Inverted Images**
4+
2. Rescaling
5+
3. Binarization
6+
4. Noise Removal
7+
5. Dilation and Erosion
8+
6. Rotation / Deskewing
9+
7. Removing Borders
10+
8. Missing Borders
11+
9. Transparency / Alpha Channel
12+
"""
13+
14+
from __future__ import annotations
15+
16+
import logging
17+
import sys
18+
from copy import copy
19+
from pathlib import Path
20+
from typing import TYPE_CHECKING, NoReturn
21+
22+
import cv2
23+
from deprecated import deprecated
24+
from icecream import ic
25+
from matplotlib import pyplot as plt
26+
27+
if sys.version_info >= (3, 11):
28+
from typing import Self
29+
else:
30+
from typing_extensions import Self
31+
32+
if TYPE_CHECKING:
33+
import numpy as np
34+
35+
IMG_DIR: Path = Path(__file__).parents[1] / 'generic_data' / 'text_img'
36+
37+
38+
def who(cls):
39+
"""Its Class name."""
40+
cls.class_name = cls.__name__
41+
return cls
42+
43+
44+
def add_method(method):
45+
"""Adding method into class."""
46+
47+
def wrapper(cls):
48+
"""Set method into class."""
49+
cls.method = method
50+
51+
52+
@deprecated(
53+
version='1.69.0a5',
54+
reason='use another implementation updated into dojo20250114.',
55+
)
56+
class PreprocessImageOCR:
57+
"""Preprocess Image."""
58+
59+
def __init__(self, img_path: Path | None = None):
60+
"""Initializer."""
61+
self.dpi: float = 80.0
62+
self._img_path: Path = None
63+
self._img_data: np.ndarray = None
64+
self.img: np.ndarray = None
65+
self.img_path = img_path
66+
67+
@property
68+
def img_path(self) -> Path:
69+
"""Imagem file."""
70+
return self._img_path
71+
72+
@img_path.setter
73+
def img_path(self, value: Path) -> NoReturn:
74+
self._img_path = value
75+
try:
76+
self._img_data = plt.imread(self._img_path)
77+
self.img = copy(self._img_data)
78+
except AttributeError:
79+
pass
80+
logging.info(ic('Image load'))
81+
logging.debug(ic(self._img_path))
82+
83+
def save(self, fout: Path | None = None) -> Path:
84+
"""Save current image."""
85+
fout = fout or (
86+
Path.cwd() / f'{self.img_path.stem}_latest{self.img_path.suffix}'
87+
)
88+
fout = fout.resolve()
89+
fout.parent.mkdir(exist_ok=True)
90+
cv2.imwrite(fout, self.img)
91+
logging.info(ic('Image saved.'))
92+
logging.debug(ic(fout))
93+
return fout
94+
95+
def reset(self) -> Self:
96+
"""Reset to original image."""
97+
self.img = copy(self._img_data)
98+
logging.info(ic('Image reseted.'))
99+
return self
100+
101+
def display(self, img_path: Path | None = None) -> bool:
102+
"""Display image on screen.
103+
104+
https://stackoverflow.com/questions/28816046/displaying-different-images-with-actual-size-in-matplotlib-subplot
105+
"""
106+
self.img_path = img_path
107+
108+
height, width = self.img.shape[:2]
109+
110+
# What size does the figure need to be in inches to fit the image?
111+
figsize = width / self.dpi, height / self.dpi
112+
113+
# Create a figure of the right size with
114+
# one axes that takes up the full figure
115+
fig = plt.figure(figsize=figsize)
116+
ax = fig.add_axes([0, 0, 1, 1])
117+
118+
# Hide spines, ticks, etc.
119+
ax.axis('off')
120+
121+
# Display the image.
122+
ax.imshow(self.img, cmap='gray')
123+
124+
plt.show()
125+
126+
127+
@who
128+
class PPIOCR(PreprocessImageOCR):
129+
"""New class."""
130+
131+
@deprecated(
132+
version='1.69.0a6',
133+
reason='use another implementation updated into dojo20250114.',
134+
)
135+
def inverted(self) -> Self:
136+
"""Inverter bit image."""
137+
self.img = cv2.bitwise_not(self.img)
138+
return self
139+
140+
141+
if __name__ == '__main__':
142+
o = PPIOCR(IMG_DIR / 'letter.jpg')
143+
o.display()
144+
o.inverted().display()

0 commit comments

Comments
 (0)