ApyHTML19 commited on
Commit
22e1f7f
·
verified ·
1 Parent(s): 67d1fb6

Organize repo: add examples, model code and updated model card

Browse files
.gitattributes CHANGED
@@ -33,3 +33,9 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ assets/detection_example.png filter=lfs diff=lfs merge=lfs -text
37
+ examples/inputs/house_and_plate.png filter=lfs diff=lfs merge=lfs -text
38
+ examples/inputs/street.png filter=lfs diff=lfs merge=lfs -text
39
+ examples/outputs/house_and_plate_anonymized.png filter=lfs diff=lfs merge=lfs -text
40
+ examples/outputs/plate_anonymized.jpg filter=lfs diff=lfs merge=lfs -text
41
+ examples/outputs/street_anonymized.png filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,42 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <p align="center">
2
- <img src="panner.png" width="1200" alt="Vision-AN18 banner" />
3
  </p>
4
 
5
- # Vision-AN18
6
 
7
  Privacy-preserving computer vision for detecting and anonymizing sensitive visual information in street images.
8
 
9
- ## Overview
 
 
10
 
11
- Vision-AN18 is a deep learning pipeline designed to detect license plates and house numbers in public images (STREET VIEW GOOGLE MAPS DESIGN MODEL), then blur the identified regions to preserve privacy while keeping the overall image useful.
12
 
13
- The project combines:
 
 
 
 
14
 
15
- - a data preparation pipeline,
16
- - a Faster R-CNN detection model,
17
- - an anonymization module,
18
- - a FastAPI inference service,
19
- - a simple Gradio demo for testing.
20
 
21
- ## Key Features
 
 
22
 
23
- - License plate detection
24
- - House number detection
25
- - Gaussian blur anonymization
26
- - Dataset preprocessing pipeline
27
- - Inference and deployment support
28
- - GPU-ready training workflow
29
 
30
  ## Model
31
 
32
- The detection model is based on Faster R-CNN with a ResNet-50 + FPN backbone.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
- Training was performed on an NVIDIA RTX 5050, and the model is intended to be shared on Hugging Face for easier reproducibility and deployment.
 
 
 
 
 
 
 
35
 
36
- ## Repository Structure
37
 
38
- Avainble soon on github repo
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
- ## License
41
 
42
- This project is intended for research and privacy-oriented computer vision experiments.
 
1
+ ---
2
+ library_name: pytorch
3
+ pipeline_tag: object-detection
4
+ tags:
5
+ - object-detection
6
+ - faster-rcnn
7
+ - torchvision
8
+ - license-plate-detection
9
+ - house-number-detection
10
+ - anonymization
11
+ - privacy
12
+ - street-view
13
+ ---
14
+
15
  <p align="center">
16
+ <img src="assets/banner.png" width="1200" alt="Vision-AN18 banner" />
17
  </p>
18
 
19
+ # Vision-AN18 — Faster R-CNN
20
 
21
  Privacy-preserving computer vision for detecting and anonymizing sensitive visual information in street images.
22
 
23
+ Vision-AN18 detects **license plates** and **house numbers** in street-level images (Google Street View style), then blurs the detected regions to preserve privacy while keeping the rest of the image useful.
24
+
25
+ ## Examples
26
 
27
+ Original image on the left, output of the anonymization pipeline on the right (Gaussian blur applied to each detected box).
28
 
29
+ | Original | Anonymized |
30
+ | :---: | :---: |
31
+ | ![Plate original](examples/inputs/plate.jpg) | ![Plate anonymized](examples/outputs/plate_anonymized.jpg) |
32
+ | ![House and plate original](examples/inputs/house_and_plate.png) | ![House and plate anonymized](examples/outputs/house_and_plate_anonymized.png) |
33
+ | ![Street original](examples/inputs/street.png) | ![Street anonymized](examples/outputs/street_anonymized.png) |
34
 
35
+ ### Raw detection
 
 
 
 
36
 
37
+ <p align="center">
38
+ <img src="assets/detection_example.png" width="700" alt="License plate detection example" />
39
+ </p>
40
 
41
+ > ⚠️ **Known limitations** — license plate detection is reliable. House number detection is still imperfect (scale bias inherited from the SVHN dataset used for this class), and the model can produce false positives on large flat regions such as windows or walls (see the third example).
 
 
 
 
 
42
 
43
  ## Model
44
 
45
+ | | |
46
+ | --- | --- |
47
+ | Architecture | Faster R-CNN |
48
+ | Backbone | ResNet-50 + FPN |
49
+ | Framework | PyTorch / torchvision |
50
+ | Classes | `0: background`, `1: license_plate`, `2: house_number` |
51
+ | Input size | min 800 / max 1333 px (resized internally) |
52
+ | Training data | OpenLPR (plates) + SVHN (house numbers) |
53
+ | Training hardware | NVIDIA RTX 5050 |
54
+
55
+ ## Usage
56
+
57
+ ```python
58
+ import torch
59
+ from PIL import Image
60
+ import torchvision.transforms.functional as TF
61
+ from huggingface_hub import snapshot_download
62
+ import sys
63
+
64
+ repo_dir = snapshot_download("ApyHTML19/Faster-RCNN-Vision-ANN18")
65
+ sys.path.insert(0, repo_dir)
66
+ from models.faster_rcnn import create_model
67
+
68
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
69
+
70
+ model = create_model(num_classes=3, pretrained_backbone=False)
71
+ checkpoint = torch.load(f"{repo_dir}/best_model.pth", map_location=device)
72
+ model.load_state_dict(checkpoint.get("model_state_dict", checkpoint))
73
+ model.to(device).eval()
74
+
75
+ CLASS_NAMES = {1: "license_plate", 2: "house_number"}
76
+
77
+ image = Image.open(f"{repo_dir}/examples/inputs/plate.jpg").convert("RGB")
78
+ with torch.inference_mode():
79
+ output = model([TF.to_tensor(image).to(device)])[0]
80
+
81
+ for box, label, score in zip(output["boxes"], output["labels"], output["scores"]):
82
+ if score >= 0.5:
83
+ print(CLASS_NAMES[int(label)], f"{score:.3f}", [round(v) for v in box.tolist()])
84
+ ```
85
+
86
+ ### Blurring the detections
87
+
88
+ ```python
89
+ import cv2
90
 
91
+ img = cv2.imread(f"{repo_dir}/examples/inputs/plate.jpg")
92
+ for box, score in zip(output["boxes"], output["scores"]):
93
+ if score < 0.5:
94
+ continue
95
+ x1, y1, x2, y2 = map(int, box.tolist())
96
+ img[y1:y2, x1:x2] = cv2.GaussianBlur(img[y1:y2, x1:x2], (51, 51), 0)
97
+ cv2.imwrite("anonymized.jpg", img)
98
+ ```
99
 
100
+ ## Repository structure
101
 
102
+ ```text
103
+ Faster-RCNN-Vision-ANN18/
104
+ ├── README.md # this model card
105
+ ├── best_model.pth # trained checkpoint
106
+ ├── models/ # model definition (Faster R-CNN + ResNet-50 FPN backbone)
107
+ │ ├── __init__.py
108
+ │ ├── backbone.py
109
+ │ └── faster_rcnn.py
110
+ ├── examples/
111
+ │ ├── inputs/ # original test images
112
+ │ └── outputs/ # anonymized results
113
+ └── assets/ # banner and illustration images
114
+ ```
115
 
116
+ ## Intended use
117
 
118
+ Research and privacy-oriented computer vision experiments: anonymizing license plates and house numbers in street-level imagery before storage or publication. Not intended for surveillance or for identifying individuals.
panner.png → assets/banner.png RENAMED
File without changes
best_model13.pth → assets/detection_example.png RENAMED
File without changes
examples/inputs/house_and_plate.png ADDED

Git LFS Details

  • SHA256: 1df9c34967daf21593218096b26ef8a8e0c5b0c8a4435df7a3ea65ae787a742e
  • Pointer size: 131 Bytes
  • Size of remote file: 468 kB
examples/inputs/plate.jpg ADDED
examples/inputs/street.png ADDED

Git LFS Details

  • SHA256: e88cc9789ebcae5a5010a871a498ad1fa7145cbbd937eb72c3cb7482e648a1cf
  • Pointer size: 131 Bytes
  • Size of remote file: 504 kB
examples/outputs/house_and_plate_anonymized.png ADDED

Git LFS Details

  • SHA256: dd3b11ccc464af837a5f0f4b285dace43c9dd345e7e4e65487bd97c1e93bb8c8
  • Pointer size: 131 Bytes
  • Size of remote file: 452 kB
examples/outputs/plate_anonymized.jpg ADDED

Git LFS Details

  • SHA256: b6d7b837206df05f314de4e06e570fb5c419fdc2321272598adc6f1218a7d226
  • Pointer size: 131 Bytes
  • Size of remote file: 111 kB
examples/outputs/street_anonymized.png ADDED

Git LFS Details

  • SHA256: 2326ec34250f5f1cd0c04acae38dbdffc03e979a6b7c359cf264e39e845ead8a
  • Pointer size: 131 Bytes
  • Size of remote file: 457 kB
models/__init__.py ADDED
File without changes
models/backbone.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ from torchvision.models import resnet50, ResNet50_Weights
4
+ from torchvision.models._utils import IntermediateLayerGetter
5
+ from torchvision.ops import FeaturePyramidNetwork
6
+ from torchvision.ops.feature_pyramid_network import LastLevelMaxPool
7
+ class ResNet50FPNBackbone(nn.Module):
8
+ def __init__(self, pretrained=True, out_channels=256):
9
+ super().__init__()
10
+ weights = ResNet50_Weights.DEFAULT if pretrained else None
11
+ resnet = resnet50(weights=weights)
12
+ self.body = IntermediateLayerGetter(
13
+ resnet,
14
+ return_layers={
15
+ "layer1": "c2",
16
+ "layer2": "c3",
17
+ "layer3": "c4",
18
+ "layer4": "c5"
19
+ }
20
+ )
21
+ self.fpn = FeaturePyramidNetwork(
22
+ in_channels_list=[
23
+ 256,
24
+ 512,
25
+ 1024,
26
+ 2048
27
+ ],
28
+ out_channels=out_channels,
29
+ extra_blocks=LastLevelMaxPool()
30
+ )
31
+ self.out_channels = out_channels
32
+ def forward(self, x):
33
+ features = self.body(x)
34
+ features = self.fpn(features)
35
+ return features
models/faster_rcnn.py ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from torchvision.models.detection import FasterRCNN
3
+ from torchvision.models.detection.rpn import AnchorGenerator
4
+ from torchvision.ops import MultiScaleRoIAlign
5
+ from .backbone import ResNet50FPNBackbone
6
+ class VisionAN18FasterRCNN(FasterRCNN):
7
+ def __init__(
8
+ self,
9
+ num_classes=3,
10
+ pretrained_backbone=True
11
+ ):
12
+ backbone = ResNet50FPNBackbone(
13
+ pretrained=pretrained_backbone,
14
+ out_channels=256
15
+ )
16
+ anchor_generator = AnchorGenerator(
17
+ sizes=(
18
+ (32,),
19
+ (64,),
20
+ (128,),
21
+ (256,),
22
+ (512,)
23
+ ),
24
+ aspect_ratios=(
25
+ (0.5, 1.0, 2.0),
26
+ (0.5, 1.0, 2.0),
27
+ (0.5, 1.0, 2.0),
28
+ (0.5, 1.0, 2.0),
29
+ (0.5, 1.0, 2.0)
30
+ )
31
+ )
32
+ roi_pooler = MultiScaleRoIAlign(
33
+ featmap_names=[
34
+ "c2",
35
+ "c3",
36
+ "c4",
37
+ "c5",
38
+ "pool"
39
+ ],
40
+ output_size=7,
41
+ sampling_ratio=2
42
+ )
43
+ super().__init__(
44
+ backbone=backbone,
45
+ num_classes=num_classes,
46
+ rpn_anchor_generator=anchor_generator,
47
+ box_roi_pool=roi_pooler,
48
+ min_size=800,
49
+ max_size=1333,
50
+ rpn_pre_nms_top_n_train=2000,
51
+ rpn_pre_nms_top_n_test=1000,
52
+ rpn_post_nms_top_n_train=1000,
53
+ rpn_post_nms_top_n_test=300,
54
+ rpn_nms_thresh=0.7,
55
+ rpn_fg_iou_thresh=0.7,
56
+ rpn_bg_iou_thresh=0.3,
57
+ box_score_thresh=0.05,
58
+ box_nms_thresh=0.5,
59
+ box_detections_per_img=100
60
+ )
61
+ self.class_names = {
62
+ 0: "background",
63
+ 1: "license_plate",
64
+ 2: "house_number"
65
+ }
66
+ def print_architecture(self):
67
+ print("=" * 60)
68
+ print("VISION-AN18 FASTER R-CNN")
69
+ print("=" * 60)
70
+ print("Backbone : ResNet50")
71
+ print("Backbone : Pretrained ImageNet")
72
+ print("Neck : Feature Pyramid Network")
73
+ print("RPN : Region Proposal Network")
74
+ print("ROI Pooler : MultiScale RoI Align")
75
+ print("Detection : Fast R-CNN Head")
76
+ print("Classes : 3")
77
+ print(" 0 : background")
78
+ print(" 1 : license_plate")
79
+ print(" 2 : house_number")
80
+ print("=" * 60)
81
+ def create_model(
82
+ num_classes=3,
83
+ pretrained_backbone=True
84
+ ):
85
+ model = VisionAN18FasterRCNN(
86
+ num_classes=num_classes,
87
+ pretrained_backbone=pretrained_backbone
88
+ )
89
+ return model